오늘은 데이터베이스와 JPA 등에 관한 내용이다.
ORM은 Object Relational Mapping의 줄임말로 객체 관계 매핑을 의미한다. 즉, 자바와 같은 객체지향 언어에서 의미하는 객체와 RDB의 테이블을 자동으로 매핑하는 방법이다.
클래스와 데이터베이스 테이블은 불일치와 제약사항이 존재하는데 이를 해결해주는 역할을 한다.
ORM을 사용하며 데이터베이스 쿼리를 객체지향적으로 조작할 수 있다.
재사용 및 유지보수가 편리하다
데이터베이스에 대한 종속성이 줄어든다
JPA는 자바 진영의 ORM 기술 표준으로 채택된 인터페이스 모음이다. 개념적으로 보자면 ORM이 큰 개념이고 JPA는 더 구체화된 스펙을 포함한다.
즉, JPA 또한 실제로 동작하는 것이 아닌 어떻게 동작해야 하는지 메커니즘을 정리한 표준 명세이다.
JPA는 내부적으로 JDBC를 사용한다. JPA는 개발자 대신 적절한 SQL을 생성하고 데이터베이스를 조작해서 객체를 자동 매핑하는 역할을 수행한다.
JPA 기반 구현체는 3가지가 있다. 이 중 가장 많이 사용되는 구현체는 하이버네이트이다.
이미지출처
하이버네이트는 자바의 ORM 프레임워크로 JPA가 정의하는 인터페이스를 구현하고 있는 JPA 구현체 중 하나이다.
Spring Data JPA는 하이버네이트의 기능을 더욱 편하게 사용하도록 모듈화 한 것이다. JPA를 편리하게 사용할 수 있도록 지원하는 스프링 하위 프로젝트 중 하나이다.
하이버네이트의 EntityManager를 직접 다루지 않고 Repository를 정의해 사용함으로써 스프링이 적합한 쿼리를 동적으로 생성한다.
필자도 개발 처음에는 EntityManager를 사용하여 개발하다 Spring Data JPA를 사용해보니 신세계였다..
따라서 정리해보면 ORM을 구체화한 JPA가 있고, JPA를 구현한 Hibernate를 더 사용하기 편하도록 모듈화 한 Spring Data JPA를 사용한다고 할 수 있겠다.
영속성 컨텍스트(Persistence Context)는 엔티티와 레코드의 괴리를 해소하는 기능과 객체를 보관하는 기능을 수행한다.
애플리케이션에서 바로 데이터베이스로 저장되지 않고 영속성 컨텍스트를 거쳐서 데이터베이스에 저장된다고 보면 될 것 같다.
엔티티 객체가 영속성 컨텍스트에 들어와 JPA의 관리 대상이 되는 시점부터는 해당 객체를 영속 객체라고 부른다.
영속성 컨텍스트는 세션 단위의 생명주기를 가진다. 데이터베이스에 접근하기 위한 세션이 생성되면 영속성 컨텍스트가 만들어지고, 세션이 종료되면 영속성 컨텍스트도 없어진다.
엔티티 매니저는 이름 그대로 엔티티를 관리하는 객체이다. 이는 데이터베이스에 접근해 CRUD 작업을 수행한다.
Spring Data JPA에서도 Repository의 내부 구현체인 SimpleJpaRepository가 엔티티 매니저를 사용한다.
엔티티 매니저는 엔티티 매니저 팩토리가 만드는데, 이는 애플리케이션에서 단 하나만 생성되며, 모든 엔티티가 공유해서 사용한다.
엔티티 매니저 팩토리로 생성된 엔티티 매니저는 엔티티를 영속성 컨텍스트에 추가해서 영속 객체로 만드는 작업을 수행하고, 영속성 컨텍스트와 데이터베이스를 비교하여 실제 데이터베이스를 대상으로 작업을 수행한다.
Repository는 기본적인 메서드를 제공하지만 메서드의 이름에 따라 커스텀 메서드도 생성할 수 있다.
메서드에 이름을 붙일 때는 첫 단어를 제외한 이후 단어들의 첫 글자를 대문자로 설정해야 JPA에서 정상적으로 인식하고 쿼리를 자동적으로 만들어준다.
FindBy: SQL의 Where 절
AND,OR: 조건을 어러개 설정
Like/NotLike: SQL문의 Like와 동일 기능 수행
특정 문자를 포함하는지 여부를 조건으로 추가
비슷한 키워드로 Containing, Contains, isContaining이 있다.
StartsWith/StartingWith
EndsWith/EndingWith
IsNull/IsNotNull
True/False
Before/After
LessThan/GreaterThan
Between
OrderBy: SQL에서 ORDER BY와 동일한 기능 수행
countBy: SQL에서 COUNT와 동일한 기능 수행
Lombok은 클래스를 생성할 때 반복적으로 사용하는 getter/setter 같은 메서드들을 어노테이션으로 대체해서 코드를 줄여주고 가독성을 향상 시켜준다.
Getter/Setter
NoArgsConstructor
AllArgsConstructor
RequiredArgsConstructor
ToString
toString() 메서드를 생성하는 어노테이션
필드의 값을 문자열로 조합해서 리턴한다.
숨겨야 할 정보가 있다면 exclude 속성을 사용하면 된다. (Ex. ToString(exclude = "name"))
EqualsAndHashCode
객체의 동등성(Equality)와 동일성(Identity)을 비교하는 연산 메서드 생성
Equality: 객체의 내용이 같은지
Identity: 두 객체가 같은 객체인지
Data
Getter/Setter, NoArgsConstructor, ToString, EqualsAndHashCode를 모두 포함한다
@Data로 위 어노테이션을 한번에 생성할 수 있다.