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

hyHA·2023년 12월 15일
0
post-custom-banner

ORM은 객체와 데이터베이스를 연결하는 프로그래밍 기법이다. 즉, 관계형 데이터베이스와 프로그램 간의 통신개념이다.

JPA는 관계형 데이터베이스를 사용하는 방식을 정의한 기술 명세이다

하이버네이트는 JPA의 구현체이다

스프링 데이터 JPA는 JPA를 쓰기 편하게 만들어 놓은 모듈이다.

아래에서 더 자세히 알아보자

데이터베이스란?

데이터를 효율적으로 보관하고 꺼내볼 수 있는 곳. 많은 사람이 안전하게 데이터를 사용하고 관리할 수 있다.

데이터베이스 관리자. DBMS

데이터베이스를 관리하기 위한 소프트웨어를 DBMS라고 한다.
데이터베이스는 많은 사람들이 공유할 수 있어야 하므로 동시접근을 할 수 있어야 하는데, 이런 요구사항을 만족하면서 효율적으로 관리하고 운영하는 것을 말한다.

따라서 MySQL, 오라클은 데이터베이스가 아니라 DBMS다.
DBMS는 특징에 따라 관계형, 객체-관계형, 도큐먼트형, 비관계형으로 분류한다.

관계형 DBMS

테이블 형태로 이루어진 데이터 저장소.

  • ex) H2, MySQL

꼭 알아야 할 데이터베이스 용어

  • 쿼리
    • 데이터베이스에서 데이터를 조회, 생성, 삭제, 수정하는 명령문.
    • SQL이라는 데이터베이스 전용 언어를 사용하여 작성한다.

graphQL이란?

  • 페이스북에서 만든 API 를 위한 쿼리 언어
  • GraphQL은 데이터베이스에 종속되지 않고, 어떠한 데이터 소스에도 적용 가능
  • 클라이언트는 필요한 데이터를 명시하고, 서버는 해당 요청에 응답
  • GraphQL은 실시간 데이터를 다루기에 적합
  • GraphQL은 동적 스키마를 사용하며, 새로운 필드나 타입을 추가하거나 변경할 수 있음
  • GraphQL은 단일 엔드포인트를 사용하여 여러 리소스에 대한 데이터를 요청할 수 있다

ORM이란?

객체데이터베이스를 연결하여 데이터베이스를 다룰 수 있게 하는 프로그래밍 기법이다
데이터베이스의 값을 마치 객체처럼 사용할 수 있다. sql을 몰라도 자바 언어로만 데이터베이스에 접근해서 원하는 데이터를 받아올 수 있다. 물론 SQL을 공부하면 그 편리함을 더 크게 느낄 수 있다.

ORM의 장단점

장점

  1. sql을 직접 작성하지 않고 사용하는 언어로 DB에 접근할 수 있다.
  2. 객체지향적으로 코드를 작성할 수 있기 때문에 비즈니스 로직에만 집중할 수 있다.
  3. 데이터베이스 시스템에 대한 종속성이 줄어듬. mysql에서 postgreSQL로 전환한다 해도 추가로 드는 작업이 거의 없음
  4. 매핑하는 정보가 명확하여 ERD에 대한 의존도를 낮출 수 있고 유지보수할 때 편리

단점

  1. 프로젝트의 복잡성이 커질수록 사용 난이도도 올라감
  2. 복잡하고 무거운 쿼리는 ORM으로 해결 불가능함

JPA와 하이버네이트

DBMS에도 여러 종류가 있는 것처럼 ORM에도 여러 종류가 있다. 자바에서는 JPA를 표준으로 사용한다.

JPA란

JPA는 자바에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스이다

인터페이스이므로 실제 사용을 위해 ORM 프레임워크(대표적으로 하이버네이트)를 추가로 선택한다.

하이버네이트는 JPA 인터페이스를 구현한 구현체이자 자바용 ORM 프레임워크. 내부적으로 JDBC API를 사용한다.

JPA의 중요한 컨셉에는 엔티티 매니저와 영속성 컨텍스트라는 것이 있다.

엔티티 매니저

엔티티

엔티티는 본질적으로는 자바 객체이므로 일반 객체와 다르지 않다.

하지만 DB 테이블과 직접 연결된다는 특징이 있어 구분지어 부르는 것. 즉, 테이블과 매핑되는 객체이다.

엔티티 매니저

엔티티를 관리해 DB와 애플리케이션 사이에서 객첼를 생성, 수정, 삭제하는 역할을 한다. 이런 엔티티 매니저를 만드는 곳이 엔티티 매니저 팩토리이다.

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

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

영속성 컨텍스트

엔티티 매니저는 엔티티를 영속성 컨텍스트에 저장한다.

영속성 컨텍스트는 JPA의 중요한 특징 중 하나로, 엔티티를 관리하는 가상의 공간이다. 이로 인해 DB에서 데이터를 효과적으로 가져오고 편하게 사용할 수 있는 것.

영속성 컨텍스트에는 아래의 특징이 있다

1차 캐시

영속성 컨텍스트는 내부에 1차 캐시를 가지고 있다.

엔티티를 조회하면 1차 캐시에서 데이터를 조회한다. 값이 없으면 DB에서 조회하여 1차 캐시에 저장 후 반환한다. 이를 통해 빠르게 데이터를 조회할 수 있다.

  • 캐시의 키 : 엔티티의 기본키 역할을 하는 식별자(@Id 애너테이션이 달린 기본키)
  • 캐시의 값 : 엔티티

쓰기 지연

트랜잭션을 커밋하기 전까지 쿼리를 모았다가, 트랜잭션 커밋 시 모았던 쿼리를 한번에 실행. 이를 통해 DB시스템의 부담을 줄일 수 있다

변경 감지(dirty checking)

트랜잭션을 커밋하면 1차 캐시에 저장되어 있는 엔티티의 값과 비교하여 변경된 값이 있다면, 변경 사항을 감지해 변경된 값을 DB에 자동으로 반영.

지연 로딩

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

엔티티의 상태

상태의미
분리상태(detached)엔티티 매니저가 엔티티를 관리하지 않음
영속성 컨텍스트가 관리하고 있지 않음
관리상태(managed)엔티티 매니저가 엔티티를 관리함
영속성 컨텍스트가 관리함
비영속 상태(transient)엔티티 객체가 분리된 상태
영속성 컨텍스트와 전혀 관계가 없음
삭제 상태(removed)엔티티 객체가 삭제된 상태

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

스프링 데이터는 비즈니스 로직에 더 집중할 수 있도록, 엔티티의 상태를 관리하고, 필요한 시점에 커밋하는 등의 데이터베이스 사용 기능을 클래스 레벨에서 추상화하였다.

스프링 데이터에서는 제공하는 인터페이스를 통해 스프링 데이터를 사용할 수 있다.

스프링 데이터 JPA란

스프링 데이터 JPA란 스프링 데이터의 공통적인 기능에서 JPA의 기술이 추가된 기술이다. JPA를 더 편리하게 사용하는 메서드를 제공한다.

@PersistenceContext
EntityManager em;

public void join() {

	//엔티티 생성
	Member member = new Member(1L, "홍길동");
    em.persist(member);
}

위의 엔티티 생성을 위한 코드를 아래처럼 사용할 수 있다

리포지터리 역할을 하는 인터페이스를 상속받고,
제네릭<관리할 엔티티 이름, 엔티티 기본키 타입>을 입력하면 기본 CRUD 메서드를 사용할 수 있다

public interface MemberRepository extends JpaRepository<Member, Long>{ }
---
@Service 
public class MemberService{
	@Autowired
    MemberRepository memberRepository;
    
    public void test(){
    
    	//엔티티 생성
    	memberRepository.save(new Member(1L, "홍길동"));
    }
}

애너테이션

애너테이션의미
@Entity해당 클래스의 객체를 JPA가 관리하는 엔티티로 지정
@NoArgsConstructor(access = AccessLevel.PROTETCED)기본 생성자
@Idid필드를 기본키로 지정
@GeneratedValue(strategy=GernerationType.IDENTITY)기본키를 자동으로 1씩 증가
@Column(name="name", nullable = false)name이라는 not null 컬럼과 매핑

Entity

해당 클래스와 실제 DB의 테이블을 매핑한다

  1. 속성 매핑
    엔티티의 속성 중에 name을 사용하면 name의 값을 가진 테이블 이름과 매핑된다
  2. 테이블 매핑
    테이블 이름을 지정하지 않으면 클래스 이름과 같은 이름의 테이블과 매핑된다

@NoArgsConstructor

엔티티는 반드시 기본생성자가 있어야 한다.
접근 제어자는 public 또는 protected여야 한다.

public 보다는 protected가 더 안전하므로 접근 제어자가 protected인 기본 생성자를 생성한다.
@NoArgsConstructor(access = AccessLevel.PROTETCED)

참고
https://velog.io/@enjoy89/DAO-DTO-VO-Entity-%EB%9E%80
https://velog.io/@rladuswl/DTO-DAO-VO%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C

profile
룰루랄라
post-custom-banner

0개의 댓글