ORM(Object-Relational Mapping) Framework

객체관계 매핑 프레임워크로, 객체 -> ORM -> 데이터베이스와 같이 ORM은 객체와 데이터베이스 중간에 위치하고 있는 프레임워크이다.

  1. 데이터를 표현하는 객체(Entity)를 설계하고,
  2. 그 객체들을 ORM 프레임워크에서 제공하는 API를 이용해서
  3. 조작(CRUD)하면

ORM 프레임워크는 해당 객체와 매핑된 데이터베이스에 맞는 SQL을 생성해 DB 엑세스 작업을 수행한다. 즉, 객체만 이용해서 데이터베이스 엑세스 작업을 구현할 수 있다.

JPA (Java Persistence API)

JPA는 자바 진영의 ORM 기술 표준이다. 객체를 영속화시키면 테이블에 값이 저장되고, 수정하면 테이블의 값이 변경되는 등 객체를 조작하여 DB 엑세스 작업이 가능하다. JPA를 사용하는 이유는 생산성과 유지보수성이 높아지며 sql 정의 없이 CRUD 작업을 빠르게 구현할 수 있다는 장점이 있기 때문이다.

    저장 : jpa.persist(user);
    조회 : User user = jpa.find(userId);
    수정 : User user = jpa.find(userId); user.setName("홍길동");
    삭제 : jpa.remove(user);

객체 매핑

Entity(객체)를 테이블(Relation)과 매핑하는 것을 알아보도록 하자. 여기서 VO와 Entity의 차이점을 짚고 넘어가자면,

  1. VO
    • 테이블에 저장된 데이터 한 행을 담는 객체다
  2. Entity
    • 테이블과 매핑된 객체다(식별자, 참조키, 고유키 정보, 컬럼이름, 데이터타입, 크기 등의 정보를 포함한다)

클래스에 @Entity 어노테이션을 정의하면 이 객체는 JPA가 관리하는 객체임을 나타낸다. 또, 테이블의 기본키(pk)와 매핑되는 필드에 @Id 어노테이션을 정의해야 한다. 모든 Entity 클래스에는 @Id 필드가 반드시 필요하다. 매핑된 Entity의 코드를 확인하기 전에 주요 어노테이션을 살펴보도록 하자.

@Entity : JPA가 관리하는 객체
@Id : 테이블의 기본 컬럼
@Table : 테이블의 이름
@Temporal : 날짜 타입의 컬럼과 매핑시킨다

    @Temporal(TemporalType.DATE)
    private Date date; // java.util.Date객체의 날짜 정보만 테이블의 컬럼에 저장시킨다.

    @Temporal(TemporalType.TIME)
    private Date time; // java.util.Date객체의 시간 정보만 테이블의 컬럼에 저장시킨다.

    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;	// java.util.Date객체의 날짜와 시간 정보를 테이블의 컬럼에 저장시킨다.

JPA는 Column 어노테이션을 사용해 컬럼이름, null 여부, 고유키 여부, 데이터의 길이를 정의할 수 있다.
name: 필드와 매핑되는 테이블의 컬럼이름을 지정한다
nullable: null 허용 여부를 결정한다
unique: 고유키 제약 조건 적용 여부를 결정한다
length: 해당 컬럼의 데이터 길이를 지정한다

Entity 객체의 코드를 확인해 보면 다음와 같다.

    @NoArgsConstructor
    @Getter
    @Setter
    @Entity
    @Table(name = "books")
    public class Book extends BaseTimeEntity {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "book_id")
        private Long id;

        @Column(name = "book_title", nullable = false)
        private String title;

        @Column(name = "book_author", nullable = false)
        private String author;

        @Column(name = "book_publisher", nullable = false)
        private String publisher;

        @Column(name = "book_description", length = 2000)
        private String description;

        @Column(name = "book_price")
        private int price;
    }