매주 스프링 부트 핵심 가이드 를 읽으며 이전에 궁금했거나, 새롭게 알게 된 내용들을 정리할 예정이다.
(이번 주는 6장을 읽었다.)
ORM은 Object Relational Mapping의 줄임말로, 자바와 같은 객체지향 언어에서의 객체와 RDB(Relational Database, 관계형 데이터베이스)의 테이블을 자동으로 매핑하는 방법이다.
ORM을 이용하면 쿼리문을 작성이 아닌 코드로 데이터를 조작할 수 있다.
JPA는 Java Persistence API를 의미하며, 자바의 ORM 기술 표준으로 채택된 인터페이스이다. ORM이 개념이라면 JPA는 조금 더 구체적인 명세라고 생각하면 되겠다.
JPA는 내부적으로 JDBC를 사용하는데, 개발자가 JDBC를 활용하여 구현하면 SQL에 의존하게 되어 효율이 떨어진다. JPA는 이 문제점을 보완하여 개발자 대신 요구하는 기능에 맞는 SQL을 생성하고 데이터베이스를 조작하여 객체와 데이터베이스를 이어준다. 이를 기반으로 구현한 것 중 가장 많이 사용되는 것이 하이버네이트(Hibernate) 이고, 스프링 부트에서는 이 하이버네이트의 기능을 더욱 편하게 사용하도록 구현된 Spring Data JPA를 활용할 수 있다.
데이터베이스의 테이블에 대응하는 클래스이다. 데이터베이스의 테이블과 컬럼을 정의할 수 있으며, 어노테이션을 사용하여 다양한 관계를 정의할 수 있다.
@Entity
해당 클래스가 엔티티임을 명시하기 위한 어노테이션이다.
@Table
테이블 이름과 클래스 이름을 다르게 지정해야 할 때 사용한다. 명시하지 않으면 둘의 이름이 같다는 의미이며, 다른 이름을 쓰려면 @Table(name= 이름)
의 형태로 테이블명을 명시해야 한다.
@Id
테이블의 기본 값으로 사용되며, 모든 엔티티는 이 @Id
어노테이션이 필요하다.
@GeneratedValue
일반적으로 @Id
와 함께 사용되며, 어떤 방식으로 자동 생성할지를 결정한다. 흔히 데이터베이스에 위임하는 IDENTITY
를 많이 사용하며, 이 방식은 데이터베이스의 AUTO_INCREMENT
를 사용해 기본값을 생성한다.
@Column
엔티티 클래스의 멤버는 자동으로 컬럼으로 매핑되지만, 몇 가지 설정이 필요한 경우 사용한다.(컬럼의 이름, 값이 null
이 될 수 있는지, 데이터 길이, 유니크 컬럼 등)
레포지토리는 Spring Data JPA가 제공하는 인터페이스이다. JpaRepository 를 상속받는 인터페이스를 생성하여 엔티티가 생성한 데이터베이스에 접근하는 데 사용된다.
// 엔티티와 엔티티의 기본값(@id) 타입으로 지정
public interface PersonRepository extends JpaRepository<Person, Long> {
}
기본적인 메소드는 생성이 되어있지만 규칙에 따라 커스텀 메서드도 생성할 수 있다. 이를 통해 CRUD(Create, Read, Update, Delete)를 모두 구현 가능하다.
컨트롤러 클래스에 API를 구현하고, 여기에서 어떠한 요청을 받으면 데이터베이스는 서비스 클래스에서 핵심 기능을 제공한다. 데이터베이스와 밀접한 관련이 있는 객체는 엔티티 또는 DAO(Data Access Object)
를 사용하고, 클라이언트와 가까워지는 서비스 등의 레이어에서는 데이터를 주고받을 때 DTO(Data Transfer Object)
객체 를 사용하는 것이 일반적이다.
조회, 추가, 삭제 의 메소드와는 다른 점이 있다. update 라는 키워드를 따로 사용하지 않으며, 값을 find()
를 통해 가져오면 객체가 영속성 컨텍스트에 추가된다. 컨텍스트가 유지되는 상황에서 코드에서 객체의 값을 변경하고 다시 save()
를 실행하면 변경 감지를 수행하여 값을 변경해준다.