2.JPA 엔티티(Entity) 매핑과 연관 관계 매핑 |
-데이터베이스의 테이블과 엔티티 클래스 간의 매핑 작업은 JPA를 이용해 데이터베이스의 테이블과 상호 작용(데이터 저장, 수정, 조회, 삭제 등) 하기 위해 제일 먼저 해야되는 작업임
-엔티티 매핑 작업은 크게 객체와 테이블 간의 매핑, 기본키 매핑, 필드(멤버 변수)와 컬럼 간의 매핑, 엔티티 간의 연관 관계 매핑 등으로 나눌 수 있음
2-1.엔티티와 테이블 간의 매핑
-@Entity 애너테이션
● 클래스 레벨에 @Entity 애너테이션을 붙이면 JPA 관리 대상 엔티티로 지정
● name 애트리뷰트를 통해 엔티티 이름을 설정할 수 있음(미설정시 기본값으로 클래스 이름을 엔티티 이름으로 사용)
-@Table 애너테이션
● name 애트리뷰트를 통해 테이블 이름을 설정할 수 있음(미설정시 기본값으로 클래스 이름을 테이블 이름으로 사용)
● @Table 애너테이션은 옵션이며, 주로 테이블 이름이 클래스 이름과 달라야 할 경우에 추가함
2-2.기본키 매핑(JPA에서 지원하는 기본키 생성 전략)
-기본키 직접 할당
● 애플리케이션 코드 상에서 기본키를 직접 할당 해주는 방식 : @Id 애너테이션 추가
-기본키 자동 생성
● IDENTITY : 기본키 생성을 데이터베이스에 위임하는 전략(대표적으로 MySQL의 AUTO_INCREMENT), @GeneratedValue(strategy = GenerationType.IDENTITY)
● SEQUENCE : 데이터베이스에서 제공하는 시퀀스를 사용해서 기본키를 생성하는 전략, @GeneratedValue(strategy = GenerationType.SEQUENCE)
● TABLE : 별도의 키 생성 테이블을 사용하는 전략
● AUTO : JPA가 데이터베이스의 Dialect에 따라서 적절한 전략을 자동으로 선택하는 전략, @GeneratedValue(strategy = GenerationType.AUTO)
*Dialect : 표준 SQL 등이 아닌 특정 데이터베이스에 특화된 고유한 기능을 의미
2-3.필드(멤버 변수)와 컬럼 간의 매핑
-@Column 애너테이션
● 필드와 컬럼을 매핑해주는 애너테이션
● 만약 @Column 애너테이션이 없고, 필드만 정의되어 있다면 JPA는 기본적으로 이 필드가 테이블의 컬럼과 매핑되는 필드라고 간주하며 @Column 애너테이션에 사용되는 애트리뷰트의 값은 모두 디폴트 값이 적용됨
● 애트리뷰트
○ nullable : 컬럼에 null값을 허용할지의 여부를 지정, default = true
○ updatable : 컬럼 데이터를 수정할 수 있는지 여부를 지정, default = true
○ unique : 하나의 컬럼에 unique 유니크 제약 조건(고유한 값인지의 여부)을 설정, default = false
○ length : 컬럼에 저장할 수 있는 문자 길이를 지정, default = 255
○ name : 별도의 이름을 지정해서 엔티티 클래스 필드명과 다른 이름으로 컬럼을 생성할 수 있음
*name 애트리뷰트 생략시 엔티티 클래스 필드의 이름으로 컬럼이 생성됨
-@Transient 애너테이션 : 테이블 컬럼과 매핑하지 않겠다는 의미로 JPA가 인식
*데이터베이스에 저장도 하지 않고, 조회할 때 역시 매핑되지 않음. 주로 임시 데이터를 메모리에서 사용하기위한 용도로 사용
-@Enumerated 애너테이션 : enum 타입과 매핑할 때 사용하는 애너테이션
● EnumType.ORDINAL : enum의 순서를 나타내는 숫자를 테이블에 저장함
● EnumType.STRING : enum의 이름을 테이블에 저장함
+@Column 애너테이션이 생략되었거나 애트리뷰트가 기본값을 사용할 경우 주의 사항
int나 long 같은 원시 타입일 경우, @Column 애너테이션이 생략되면 기본적으로 nullable=false
하지만 @Column만 설정하고 nullable 애트리뷰트를 지정하지 않으면 nullable = true가 되므로 주의가 필요
+EnumType.ORDINAL 로 지정할 경우, 기존에 정의되어 있는 enum 사이에 새로운 enum 하나가 추가 된다면 그때부터 테이블에 이미 저장되어 있는 enum 순서 번호와 enum에 정의되어 있는 순서가 일치하지 않게 되는 문제가 발생함
처음부터 이런 문제가 발생하지 않도록 EnumType.STRING 을 사용하는 것을 권장
2-4.엔티티 간의 연관 관계 매핑
-엔티티 클래스 간의 관계를 만들어 주는 것
-JPA 방식의 연관 관계 매핑은 참조하는 방향성을 기준으로 단방향 연관 관계와 양방향 연관 관계로 구분하고, 엔티티 간에 참조할 수 있는 객체의 수에 따라 일대다(1:N), 다대일(N:1), 다대다(N:N), 일대일(1:1)의 연관 관계로 나눔
● 단방향 연관 관계
한쪽 클래스만 다른 쪽 클래스의 참조 정보를 가지고 있는 관계


● 양방향 연관 관계
양쪽 클래스가 서로의 참조 정보를 가지고 있는 관계
*JPA는 단방향과 양방향을 모두 지원하는 반면에 Spring Data JDBC는 단방향만 지원함

● 일대다 단방향 연관 관계
일(1)에 해당하는 클래스가 다(N)에 해당하는 객체를 참조할 수 있는 관계

● 다대일 연관 관계
다(N)에 해당하는 클래스가 일(1)에 해당하는 객체를 참조할 수 있는 관계

● 다대다 연관 관계
일반적으로 중간에 테이블을 하나 추가해서 두 개의 일대다 관계를 만들어줌

+일대다 단방향 연관 관계 대신 다대일 양방향 연관 관계를 사용하는 것이 더 좋은 방법임
(1)데이터 무결성 문제 : 연관된 엔티티가 여러 개이므로 한 엔티티의 수정이 다른 엔티티에 영향을 미칠 수 있음
(2)질의 성능 문제 : 연관된 엔티티의 수만큼 조인이 발생하기 때문에 연관된 엔티티의 수가 많아질수록 조회 성능이 저하될 수 있음
(3)객체지향 설계 원칙에 어긋남 : 한 클래스는 하나의 책임만 가져야 한다는 SRP(Single Responsibility Principle)원칙을 위반함
+일대일 매핑으로는 @OneToOne, 다대일 매핑으로는 @ManyToOne, 일대다 매핑으로는 @OneToMany를 사용하여 연관관계를 만들 수 있음
양방향 관계를 설정할 때는 양쪽 엔티티 클래스에 각각 필드를 추가하고, 그 중 하나에 mappedBy 속성을 사용하여 양방향 관계를 맺는 필드를 지정해야 함
mappedBy 속성은 양방향 연관 관계에서 역방향 매핑 정보를 가지고 있는 필드의 이름을 나타내며, 이 필드는 반대쪽 엔티티와 연관된 필드에 대한 정보를 가짐
+엔티티 간의 연관 관계 매핑 권장 방법
(1)일대다 매핑은 사용하지 않음
(2)제일 먼저 다대일 단방향 매핑부터 적용
(3)다대일 단방향 매핑을 통해 객체 그래프 탐색으로 조회할 수 없는 정보가 있을 경우, 그때 양방향 매핑을 적용
3.Spring Data JPA |
-Spring Data JDBC와 JPA를 결합한 것으로, JPA의 장점과 Spring Data JDBC의 단순함을 모두 사용할 수 있음
-Spring에서는 애플리케이션이 특정 기술에 강하게 결합되지 않도록 Spring이 추구하는 PSA(일관된 서비스 추상화)를 통해 개발자는 일관된 코드 구현 방식을 유지하도록 하고, 기술의 변경이 필요할 때 최소한의 변경만을 하도록 지원함
*데이터 액세스 기술을 Spring Data JDBC에서 Spring Data JPA로 바꿨다고 해서 실제로 코드 자체가 대폭 변경된 부분은 없음
-이미지 및 내용 출처 : code states
'부트캠프' 카테고리의 다른 글
Spring MVC - Testing part 1 (0) | 2023.03.06 |
---|---|
Spring MVC - 트랜잭션 (0) | 2023.03.03 |
HTTP 헤더(Header) (0) | 2023.02.24 |
Spring MVC - JPA 기반 데이터 액세스 계층 part 1 (0) | 2023.02.23 |
Spring MVC - JDBC 기반 데이터 액세스 계층 (0) | 2023.02.20 |