[SpringBoot] ORM Framework과 JPA
ORM(Object-Relational Mapping) Framework
객체관계 매핑 프레임워크로, 객체 -> ORM -> 데이터베이스와 같이 ORM은 객체와 데이터베이스 중간에 위치하고 있는 프레임워크이다.
- 데이터를 표현하는 객체(Entity)를 설계하고,
- 그 객체들을 ORM 프레임워크에서 제공하는 API를 이용해서
- 조작(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의 차이점을 짚고 넘어가자면,
- VO
- 테이블에 저장된 데이터 한 행을 담는 객체다
- 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;
}