JPA(jakarta.persistence)에 속한어노테이션
。@Entity,@Table,@Id,@GeneratedValue,@Column,@Enumerated,@MappedSuperclass
▶Spring과 관련이 없으므로@Entity를 선언하더라도Spring Bean으로 등록되지 않는다.
Spring에 속한어노테이션
。@Transactional,@Query
▶Spring Bean인@Service Class내에서 활용되므로 다음어노테이션을 사용
@Entity:jakarta.persistence
。JPA에서자바 클래스( =VO)를DB Entity로 등록 시 선언하는어노테이션
▶VO를DB Table와 Mapping하는DB Entity선언
。@Entity는Spring의@Component를 포함하지않으므로 선언된클래스는Spring Bean이 될 수 없음
。new를 통해 생성 직후의DB Entity 객체는비영속이므로DB Table과Mapping되지 않은 상태.
▶EntityManager.save(Entity)를 통해영속성 컨텍스트에 등록해야DB Table에Mapping되어DB Entity를 통한CRUD를 수행
▶ 생성된DB Entity에 Data를 삽입 및 수정하여영속성 컨텍스트에 등록 시매핑된DB Table에 자동으로 반영
。@Entity를 선언한클래스는 반드시기본 생성자와@Id를 선언한PK를 포함
。ddl-auto: update를 설정한 경우Auto Configuration에 의해@Entity가 선언된POJO를 식별시DB에Entity의 속성을구현 및 매핑한DB Table을 자동생성
。Hibernate의 경우 내부적으로Lazy Loading을 통한프록시 객체를 사용하므로,@Entity 클래스선언 시final이 선언이 불가능
▶final 키워드로 인해 CGLIB의동적프록시 객체생성이 봉쇄되므로.
@Entity(name="별칭명")
。JPA에 의해 인식하는Entity명을자바클래스명이 아닌 다른별칭으로 명시적으로 설정 시 사용하는 속성
。JPA에게 인식되는명칭을 설정하므로Entity Class와Mapping할DB Table을 명시적으로 설정하는것과 유사하나 이 목적으로 사용 시 실제DB Table명과매핑하는@Table(name="테이블명")을 선언하는것을 권고.
@Table(name="DBtable이름")
。@Entity Class에 선언하여DB Entity가Mapping할 실제DB Table명을 명시적으로 설정
▶DB Table명칭이JavaClass명과 다른 경우 주로 사용
@Id:jakarta.persistence
。DB Entity Class에서DB Table에서의PK로 정의할Field에 선언
▶ 주로@GeneratedValue와 함께Entity Class의Field에 선언
。@Id 필드의 경우 반드시참조형 변수로 선언
▶NPE방지
。Auto Configuration에 의한DB Table자동 생성 시 해당Field가PK의Column으로 자동설정
@GeneratedValue(strategy = GenerationType.정책, generator = "인덱스생성자명ㅈ"):jakarta.persistence
。주로@Id가 선언된PK역할의Field에 함께 선언하여DB의AUTO INCREMENT기능을 사용하도록 설정하는어노테이션
。@Id가 선언된Field는@GeneratedValue에 의해Entity 영속화 시점에서PK값이자동 할당되므로 향후Entity 객체생성 시매개변수에null로 설정하여 생성.
Strategy종류
。@Id Field에 대해 다음 전략들을 설정
GenerationType.IDENTITY:
。DB의AUTO-INCREMENT기능 사용
▶ 데이터INSERT시점에서PK값이 생성
GenerationType.SEQUENCE
。Entity의INSERT이전에DB에서PK값을 가져온 후 할당
▶PostgreSQL,Oracle에서 지원
。@SequenceGenerator 어노테이션을 활용하여SEQUENCE를 지원하지 않는DBMS( =MySQL)에도 적용 가능
▶initialValue 속성과allocationSize 속성을 통해인덱스의 증가량을 정의@Entity @SequenceGenerator( name = "SAMPLE_SEQ_GENERATOR", initialValue = 1, allocationSize = 1 ) public class SequenceMapping { @Id @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SAMPLE_SEQ_GENERATOR" // SEQUENCE 사용 시 @SequenceGenerator을 적용하여 사용해야한다. ) private Long id; }
GenerationType.TABLE
。별도의PK 관리 용도의테이블을 생성하여PK를 관리
。DBMS에 독립적으로 작용하므로, 어느DBMS에서든 사용 가능
▶ 단, 성능이 매우 안좋은 단점이 존재
@Entity @TableGenerator( name = "SAMPLE_SEQ_TABLE_GENERATOR", table = "SAMPLE_SEQUENCE_CHECK", // 해당 Generator의 Table이 DB에서 생성 pkColumnName = "SAMPLE_ACCOUNT_SEQ", // 생성될 테이블의 PK명 지정 allocationSize = 1 ) public class TableGenerationMapping { @Id @GeneratedValue( strategy = GenerationType.TABLE, generator = "SAMPLE_SEQ_TABLE_GENERATOR" )
GenerationType.AUTO:
。DB Dialect에 따라 적절한Strategy(IDENTITY,SEQUENCE등 )을 선택
▶@GeneratedValue의 기본값은AUTO
GenerationType.UUID:
。UUID Type 식별자를 자동으로 생성 및 설정
▶@Id Field의Data type은java.util.UUID로 설정되어야 한다.
。PK 길이가 매우 길고,인덱스 성능이 매우 안좋은 단점이 존재
▶분산 시스템에서 주로 활용@Id @GeneratedValue(strategy= GenerationType.UUID) private UUID id;
@Column("DBtableColumn명"):
。@Entity Class의Field에 선언하여DB Table의 특정Column과Mapping
▶ 만약Class의Field명과mapping할DB Table의Coulmn명이 동일한 경우, 따로 선언하지않아도된다.
。ddl-auto에 의한Hibernate에 의해DB Table자동 생성 시@Column("설정될Coulumn이름")이 선언된 경우 해당Column명으로DB Table을 생성
@Column(nullable = false)
。해당필드에 해당하는컬럼에NOT NULL 제약조건을 추가
▶nullable = false는Hibernate에게ddl-auto생성 시 해당필드에제약조건 : not null로 설정하는속성으로Entity에 입력되는데이터자체를 검사해주지는 않는다.
@Column(length = 1~255)
。해당필드에 해당하는문자열 컬럼(CHAR / VARCHAR)에길이 제약조건지정
▶비밀번호 필드는평문으로 설정하면 안되므로 매우 길게 설정.
@Column(columnDefinition = "자료형 DEFAULT 숫자")
。해당필드에 해당하는컬럼에NULL값이 입력된 경우기본값을 지정하도록제약조건설정
ex )INT DEFAULT 0,TEXT
@Column(unique = true)
。해당필드에unique 제약조건을 설정
@Enumerated(EnumType.STRING):jakarta.persistence.Enumerated
。@Entity Class내Enum type의필드에 선언하여Enum을DB에 저장하기위해 선언하는어노테이션
▶Enum의 값을String으로서DB에 저장
。JPA는 기본적으로@Enumerated(EnumType.ORDINAL)로Enum값이 아닌Enum인덱스로DB에 값을 넣으므로@Enumerated(EnumType.STRING)를 따로 선언해야함@Enumerated(EnumType.STRING) private Gender gender;
@Enumerated(EnumType.ORDINAL)
。ordinal:enum의인덱스를DB에 저장하는 방식으로기본설정되어있으나 사용하지 않는다.
▶Enum Class수정 시데이터 순서가 임의로 변경될 수 있으므로 사용하지 않는 것을 권고
@Async:
。선언한메서드를 별도의ThreadPool의스레드에서비동기로 실행하는어노테이션
。@EnableAsync를진입점 클래스에 선언해야비동기사용 가능.
▶ 선언하지 않으면동기로 작동
。선언된메서드와 동일한클래스내에서 호출 시 기능하지 않는다.
▶Spring Proxy를 이용하지 않으므로@Async public void asyncMethod() { System.out.println("비동기 실행"); }▶ 해당
메서드호출 시 다른스레드에서 해당메서드를 처리
@EnableAsync:
。@Async가 선언된메서드를비동기로 실행할 수 있도록 선언하는어노테이션
▶ 보통@SpringBootApplication이 선언된진입점 클래스에 선언
@MapsId("부모Entity PK명")
。부모 Entity의PK를연관관계를 통해자식 Entity에서외래키로 참조 시 해당외래키 필드에 선언하여자식 Entity의PK로매핑하는어노테이션
▶외래키를PK로 사용되도록매핑을 수행
@MapsId를 활용해부모 테이블을 참조하는외래키를기본키로 하는식별관계의테이블정의
。생성되는accountId 컬럼은PK이자FK로서 생성@Entity @Table(name = "accountnetwork") public class AccountNetwork{ @Id @Column(name = "account_id") private UUID accountId; @MapsId("id") @OneToOne(fetch = FetchType.EAGER) @JoinColumn(name = "account_id") private Account account; }create table accountnetwork ( account_id UUID not null, primary key(account_id), foreign key(account_id) references account(id) );▶ 다음처럼
PK속성과 동시에FK속성을 지닌DB Table이 생성
@MapsId를 사용하지 않는 경우@Entity class UserProfile { @Id private Long id; @OneToOne @JoinColumn(name = "user_id") private User user; }▶ 2개의
컬럼이 동기화가 되지않고 서로 다른컬럼으로서 생성됨