JaPark Bug World

[SpringBoot] 데이터베이스 조작이 편해지는 ORM 본문

개발새발/스프링부트3 백엔드 개발자 되기

[SpringBoot] 데이터베이스 조작이 편해지는 ORM

JAstory 2024. 4. 8. 23:55

5.2 ORM이란?

object-relational mapping은 자바의 객체와 데이터베이스를 연결하는 프로그래밍 기법이다. 보통은 SQL이라는 언어로 데이터베이스에 있는 값을 꺼내는 방식을 사용한다. 하지만 ORM이 있다면 데이터베이스의 값을 마치 객체처럼 사용할 수 있다. 즉, 객체와 데이터베이스를 연결해 자바 언어로만 데이터베이스를 다룰 수 있게 해주는 도구라고 할 수 있다.

 

ORM의 장점과단점

  • 장점
    • SQL을 직접 작성하지 않고 사용하는 언어로 데이터베이스에 접근 가능
    • 객체지향적으로 코드를 작성 할 수 있으므로 비즈니스 로직에만 집중 가능
    • 데이터베이스 시스템이 추상화되어 있기 때문에 MySQL에서 PostgreSQL로 전환한다고 해도 추가로 드는 작업이 거의 없다.
    • 매핑하는 정보가 명확하기 때문에 ERD에 대한 의존도로를 낮추고 유지보수가 유리
  • 단점
    • 프로젝트의 복잡성이 커질수록 사용 난이도가 상승
    • 복잡하고 무거운 커리는 ORM으로 해결이 불가능

5.3 JPA와 하이버네이트?

  • JAP(Java Persistence API)
    • 자바 객체와 데이터베이스를 연결해 데이터를 관리한다. 객체 지향 도메인 모델과 데이터베이스의 다리 역할
  • 하이버네이트(Hibernate)
    • JPA의 인터페이스를 구현한다. 내부적으로는 JDBC API를 사용

엔티티 매니저란?

엔티티(entity)

데이터베이스의 테이블과 매핑되는 객체를 의미힌다. 데이터베이스의 테이블과 직접 연결된다는 아주 특별한 특징이 있어 구분지어 부른다. 즉, 엔티티는 객체이긴 하지만 데이터베이스에 영향을 미치는 쿼리를 실행하는 객체

 

엔티티 매니저(entity manager)

엔티티를 관리해 데이터베이스와 애플리케이션 사이에서 객체를 생성, 수정, 삭제하는 등의 역할을 한다. 이러한 엔티티 매니저를 만드는 곳이 엔티티 매니저 팩토리이다. 예를 들어 회원 2명이 동시에 회원가입을 하려는 경우 엔티티 매니저 팩토리가 엔티티 매니저를 생성하고 이를 통해 데이터베이스에 회원 정보를 저장하는 것이다. 회원1을 위한 엔티티 매니저와 회원2를 위한 엔티티 매니저가 각각 생성된다. 생성된 엔티티매니저는 필요한 시점에 데이터베이스와 연결한 뒤 쿼리한다.

 

스프링부트에서는 직접 엔티티 매니저 팩토리를 만들어서 관리하지 않으며, 스프링 부트 내에서 엔티티 매니저 팩토리를 하나만 생성해서 관리하고 @PersistenceContext 또는 @Autowired 애너테이션을 사용해서 앤티티 매니저를 사용한다.

@PersistenceContext
EntityManager em;	// 프록시 엔티티 매니저, 필요할 때 진짜 엔티티 매니저 호출

 

그리고 스프링 부트는 기본적으로 빈을 하나만 생성해서 공유하므로 동시성 문제가 발생할 수 있다. 그래서 실제로는 엔티티 매니저가 아닌 실제 엔티티 매니저와 연결하는 프록시 엔티티 매니저를 사용한다. 필요할 때 데이터베이스 트랜잭션과 관련된 실제 엔티티 매니저를 호출한다.

가급적 책에 있는 모든 내용을 너무 안쓰려고 하는데.. 어쩔 수 없는 부분들이 있긴합니다........ 자세한 내용은 반드시 책을 참고하세요.. 전 개인용으로 기억하려고 정리를 하는것일뿐...

 

영속성 컨텍스트란?

엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장한다는 특징이 있다. 영속성 컨텍스트는 JPA의 중요한 특징 중 하나로, 엔티티를 관리하는 가상의 공간이다. 이것이 있기 때문에 데이터베이스에서 효과적으로 데이터를 가져올수 있고, 엔티티를 편하게 사용할 수 있다. 영속성 컨텍스트에는 1차 캐시, 쓰기 지연, 변경 감지, 지연로딩이라는 특징이 있다.

 

1차 캐시

내부에 1차 캐시를 가지고 있다. 캐시의 키는 엔티티의 @Id  애너테이션이 달린 기본키 역할을 하는 식별자이며 값은 엔티티이다. 엔티티를 조회하면 1차 캐시에서 데이터를 조회하고 값이 있으면 반환, 없으면 데이터베이스에서 조회해 1차 캐시에 저장한 다음 반환한다. 캐시된 데이터를 조회할 때에는 데이터베이스를 거치치 않아도 되므로 매우 빠르게 데이터조회가 가능하다.

 

쓰기지연

트랜잭션을 커밋하기 전까지는 데이터베이스에 실제로 질의문을 보내지 않고 쿼리를 모았다가 트랜잭션을 커밋하면 모았던 쿼리를 한번에 실행하는 것을 의미한다. 예를 들어 데이터 추가 쿼리가 3개라면 영속성 컨텍스트는 트랜잭션을 커밋하는 시점에 3개의 쿼리를 한꺼번에 전송한다. 적당한 묶음으로 쿼리를 요청할 수 있어 데이터베이스 시스템의 부담을 줄일 수 있다.

 

지연로딩

쿼리로 요청한 데이터를 애플리케이션에 바로 로딩하는 것이 아니라 필요할 때 쿼리를 날려 데이터를 조회하는 것을 의미한다. 

?????? 이게 무슨 말인가 

 

엔티티의 상태

엔티티는 4가지의 상태를 가지고 있다. 영속성 컨텍스트가 관리하고 있지 않는 분리(detached)상태, 영속성 컨텍스트가 관리하는 관리(managed)상태, 영속성 컨텍스트와 전혀 관계가 없는 비영속(transiend)상태, 삭제된(removed) 상태로 나눠진다.

안드로이드 라이프사이클하고 비슷한가..

public class EntityManagerTest {
    @Autowired
    EntityManager em;

    public void example() {
        // 1. 엔티티 매니저가 엔티티를 관리하지 않는 상태(비영속 상태)
        Member member = new Member(1L, "홍길동");

        em.persist(member);  // 2. 엔티티가 관리되는 상태
        em.detach(member);   // 3. 엔티티객체가 분리된 상태
        em.remove(member);   // 4. 엔티티 객체가 삭제된 상태
    }
}

 

1. 엔티티를 처음 만들면 비영속 상태

2. persist() 메서드를 사용해 엔티티를 관리 상태로 만들 수 있으며, Member 객체는 영속성 컨텍스트에서 상태가 관리

3. 엔티티를 영속성 컨텍스트에서 관리하고 싶지 않다면 detach() 메서드를 사용해 분리 상태로 만듦

4. 더 이상 객체가 필요없다면 remove() 메서드를 사용해 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제 가능

 

5.4 스프링 데이터와 스프링 데이터 JPA

스프링 데이터는 비즈니스 로직에 더 집중할 수 있게 데이터베이스 사용 기능을 클래스 레벨에서 추상화했다. 스프링 데이터에서 제공하는 인터페이스를 통해 스프링 데이터를 사용할 수 있다. 이 인터페이스에서는 CRUD를 포함한 여러 메서드가 포함되어 있으며 알아서 쿼리를 만들어 준다. 이외에도 페이징 처리 기능과 메서드 이름으로 자동으로 쿼리를 빌딩하는 기능이 제공, 각 데이터베이스의 특성에 맞춰 기능을 확장해 제공하는 기술도 제공 (뭐 다해줘..) 

 

스프링 데이터 JPA란?

스프링 데이터의 공통적인 기능에서 JPA의 유용한 기술이 추가된 기술. 스프링 데이터의 인터페이스인 PagingAndSortingRepository를 상속받아 JpaRepository 인터페이스를 만들었으며, JPA를 더 편리하게 사용하는 메서드를 제공한다. 스프링 데이터 JPA를 사용하면 리포지터리 역할을 하는 인터페이스를 만들어 데이터베이스의 테이블 조회, 수정, 생성, 삭제 작업을 간단히 할 수 있다. 

// 기본 CRUD 메서드를 사용하기 위한 JpaRepository 상속 예
public interface MemberRepository extends JpaRepository<Member, Long> {
}

스프링부트3 백엔드 개발자 되기: 자바 편 책(저자 신선영)을 참고하여 정리한 내용입니다.