티스토리 뷰
JPA의 역할
서로 다른 기반을 가진 두 시스템이 결합하기 위해서는 중간 다리 역할이 필요하며, JPA가 바로 그 역할이며, 존재의 이유라고 했습니다. 그러한 역할을 하기 위해서는 JPA는 양쪽 시스템에 대한 정보가 필요하며, 그 정보를 바탕으로 서로 다른 유형들을 적절하게 변환할 수 있게 됩니다.
여기서 말하는 정보는 객체의 필드의 타입(정수형, 실수형, 날짜형, ...), 테이블의 기본 키(PK), 인덱스 등이 존재한다면 해당 칼럼과 매핑될 객체의 필드를 말합니다.
엔티티(Entity)란 ?
JPA는 엔티티라는 단위로 테이블을 식별하고 관리합니다. 엔티티는 대단한 것이 아니라 우리가 작성해야 하는 비즈니스 로직을 구현한 객체라고 생각하면 됩니다. 객체의 인스턴스는 테이블의 로우로 저장되는 것이죠.
우리가 작성한 객체가 엔티티라는 것을 JPA에게 어떻게 알려줄 수 있을까요? 또한 우리가 작성하는 모든 객체를 엔티티로 사용할 수 있을까요? 우리가 작성한 객체가 엔티티가 되기 위해서는 다음을 만족해야한다고 JPA는 말합니다. (출처)
1. @Entity 애너테이션 명시하여야 한다.
2. 인수가 없는(no-arg) 생성자가 존재하여야 반드시 public 또는 protected 여야 한다.
3. 클래스, 영속화되는 필드, 메서드 모두 final 지시자를 사용해선 안된다.
4. 영속화되는 필드는 반드시 private, protected, default 지시지만을 선언할 수 있다.
속성 | 기능 | 기본값 및 설명 |
name | 엔티티의 이름을 명시합니다. | 정규화되지 않은 엔티티 클래스 명, JPQL에서의 예약된 키워드는 사용할 수 없습니다. |
한번 객체를 생성하고, 엔티티로 식별시켜보도록 하겠습니다.
하지만 위와 같은 에러가 발생합니다. 왜 그럴까요?
JPA는 엔티티 단위로 테이블을 식별한다고 했습니다. 관계형 데이터베이스에서는 테이블에는 필수적으로 기본 키(Primary Key)가 존재하여야 하는데, Student라는 객체에는 그러한 정보가 명시되어 있지 않기 때문에 에러가 있다고 알려주는 것이죠.
어떻게 엔티티에 기본 키를 명시하여 줄 수 있을까요?
@Id 애너테이션
@Id 애너테이션은 엔티티의 기본 키를 명시합니다. 기본 키가 될 필드에 직접 명시하거나, 프로퍼티(getter)에 명시할 수 있습니다.
기본 키가 될 수 있는 필드의 타입에는 어떤 것이 있을까요? 이 또한 JPA에 나와있습니다. (출처)
1. Primitive Type
2. Wrappers of Primitive Types
3. String
4. 기타 Serializable Type (java.util.Date, java.sql.Date, byte[], char[], java.math.BigDecimal, ... )
그러면 앞서 발생한 오류를 한번 고쳐보도록 하겠습니다.
기본 키의 타입으로는 Primitive Type의 long 의 Wrapper인 Long을 사용하였습니다.
에러가 사라진 것을 확인할 수 있으며 이렇게 우리가 정의한 클래스가 엔티티로 식별될 수 있도록 만들어보았습니다. 그러면 이러한 엔티티가 실제 데이터베이스에 어떻게 테이블과 매핑되는지를 확인해 보겠습니다.
엔티티와 매핑된 테이블
데이터베이스 접속 설정과 데이터베이스 설정은 생략하도록 하겠습니다.
우리가 설정한 엔티티 클래스를 식별하여 테이블과 연결된 것 을 확인할 수 있습니다.
여기서 잠깐, @Entity 애너테이션은 우리가 작성한 클래스가 엔티티라는 것을 JPA에게 알려주는 것이며, 테이블과 매핑된다는 것을 알았습니다. 그렇다면 매핑되는 테이블의 이름은 어떻게 정해줄 수 있을까요?
@Table 애너테이션
@Table 애너테이션은 엔티티에 대한 주 테이블을 지정하여줍니다. 해당 애너테이션을 생략할 경우 기본값으로 설정됩니다.
속성 | 기능 | 기본값 및 설명 |
name | 테이블의 이름을 명시합니다 | 엔티티의 이름 |
catalog | 테이블의 catalog를 명시합니다. | |
schema | 테이블의 schema를 명시합니다 | |
uniqueConstraints | DDL 생성 시 유니크 제약조건을 설정합니다. | 아무런 제약조건이 설정되지 않습니다. |
indexes | DDL 생성 시 인덱스를 설정합니다. |
@Table 애너테이션의 name 속성을 이용하여 엔티티가 매핑될 테이블의 이름을 지정하여줄 수 있습니다. 데이터베이스에 해당 테이블의 이름을 가진 테이블이 없을 경우 당연히 에러가 나겠죠 ?
테이블의 이름은 일반적으로 복수형을 많이 사용하니, 우리도 테이블의 이름을 변경하여보도록 하겠습니다.
Student 엔티티가 매핑될 테이블의 이름을 "STUDENTS"로 지정하였습니다.
정상적으로 Student 엔티티에 대한 주 테이블의 이름이 "STUDENTS"로 매핑된 것을 확인할 수 있습니다.
마무리
다음 시간에는 DDL 자동 생성 기능을 사용할 때, 테이블의 칼럼의 타입같은 정보를 기술할 수 있도록 필드에 명시할 수 있는 다양한 JPA 애너테이션들을 마저 알아보도록 하겠습니다.
'프레임워크 > JPA' 카테고리의 다른 글
[JPA]연관관계 (0) | 2022.01.14 |
---|---|
[JPA]필드와 칼럼 매핑 (0) | 2022.01.13 |
[JPA]JPA에 대하여 (0) | 2022.01.13 |
- Total
- Today
- Yesterday
- dsu
- 코딩인터뷰
- 해쉬
- dp
- 스트림
- JPA
- 구현
- 코드 스니펫
- sql
- k8s
- 알고리즘
- Uber
- 카카오
- 오늘의집
- set
- TDD
- 탐욕법
- dfs
- Java
- 비트연산
- BFS
- 연결리스트
- 정렬
- kotlin
- 스택
- 프로그래머스
- 문자열
- 회고
- 쓰레드
- 우선순위큐
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |