05장 데이터베이스 조작이 편해지는 ORM

올찬·2023년 9월 30일
0

💡 이 글은 골든래빗 《스프링 부트 3 백엔드 개발자 되기 - 자바 편》의 05장 써머리입니다.

핵심 키워드

  • DBMS(Database Management System): DB를 관리하기 위한 소프트웨어, 관리 특징에 따라 관계형(가장 많이 사용), 객체-관계형, 도큐먼트형, 비관계형 등으로 분류됨. 여러 사람이 동시 접근할 수 있어야 함

    • H2: 자바로 작성된 관계형 데이터 베이스, 데이터를 외부 스토리지가 아닌 메모리에 저장하기 때문에 애플리케이션이 종료되면 데이터는 삭제됨
  • ORM(Object-Relational Mapping): 자바의 객체와 DB를 연결하는 프로그래밍 기법. 자바 언어로만 DB를 다룰 수 있게 함

    • 장점
      • SQL을 직접 작성하지 않고 DB에 접근 가능
      • 객체지향적으로 코드를 작성할 수 있어서 비즈니스 로직에 집중 가능
      • 인터페이스를 통해 DBMS를 다루기 때문에 DBMS에 대한 종속성이 낮음
      • 매핑하는 정보가 명확하기 때문에 ERD에 대한 의존도가 낮고 유지보수에 유리
    • 단점
      • 프로젝트의 복잡성이 커질수록 사용 난이도 증가
      • 복잡하고 긴 쿼리는 ORM으로 해결이 불가능할 수 있음
  • JPA(Java Persistence API): 자바에서 관계형 데이터베이스를 사용하는 방법을 정의한 인터페이스

  • 하이버네이트(Hibernate): 자바용 ORM 프레임워크이자 JPA의 구현체, 내부적으로는 JDBC API 사용

    • JDBC(Java Database Connectivity) API: Java 언어로 여러 가지 DB를 다룰 수 있게 하는 기술, java.sql, javax.sql 패키지로 구성되어 있음. 이를 쓰기 위해서는 사용할 DB에 맞는 JDBC 드라이버가 필요함
  • 엔티티(Entity): 데이터베이스의 테이블과 매핑되는 객체

    • 엔티티 매니저(Entity Manager): 엔티티를 관리해 DB와 애플리케이션 사이에서 객체를 CRUD하는 역할, 프록시 객체를 사용해 동시성 문제 해결
    • 엔티티 매니저 팩토리(Entity Manager Factory): 엔티티 매니저를 만드는 곳, 스프링 부트 내부에서 1개만 생성해 관리, EntitnManager를 필드로 선언하고 @PersistenceContext, @Autowired 붙여 사용 가능
  • 영속성 컨텍스트: 엔티티를 관리하는 가상의 공간(컨테이너), 엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장하여 관리함, 다음 4가지 특징이 있음

    • 1차 캐시: 영속성 컨텍스트 내부에 존재, 엔티티의 @Id를 키로 하여 엔티티 자체를 저장. 엔티티 조회 시 임시 공간으로 활용하여 DB를 거치지 않고 처리 가능
    • 쓰기 지연(Transactional write-behind): 데이터를 추가하는 쿼리를 모았다가 트랜잭션 커밋 시 한 번에 실행, DB 접근 횟수 감소로 시스템 부담 줄임
    • 변경 감지: 트랜잭션을 커밋하면 1차 캐시에 저장된 엔티티의 값과 현재 엔티티의 값을 비교해 변경사항을 DB에 자동으로 반영하는 기능
    • 지연 로딩(Lazy Loading): 실제 필요할 때 쿼리를 날려 데이터를 조회하는 방식, 엔티티 간 연관관계 매핑 시 사용됨
  • 스프링 데이터 JPA: 스프링 데이터의 공통적인 기능에 JPA의 유용한 기능이 추가된 기술, 엔티티 매니저를 선언하지 않고 JpaRepository 인터페이스에 선언된 메서드로 엔티티를 다룰 수 있음

    package me.allchan.springbootdeveloper;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    import java.util.Optional;
    
    @Service
    public class MemberService {
    
        @Autowired
        MemberRepository memberRepository;
    
        public void test() {
            // 생성
            memberRepository.save(new Member(1L, "A"));
    
            // 조회
            Optional<Member> member = memberRepository.findById(1L);
            List<Member> allMembers = memberRepository.findAll();
    
            // 삭제
            memberRepository.deleteById(1L);
        }
    }
    package me.allchan.springbootdeveloper;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface MemberRepository extends JpaRepository<Member, Long> {
    }
    
profile
묘공단 스터디 블로그

0개의 댓글