본문 바로가기
SpringBoot/(책)스프링부트 시작하기

[springboot] 14. 스프링 데이터 jpa 2(엔티티 생성하기)

by 평범한kiki 2023. 5. 6.

* 폴더구조

* 엔티티 생성하기

- @Entity: 해당클래스가 JPA의 엔티티임을 나타냄. 엔티티클래스는 테이블과 매핑됨
- @Table(name="t_jpa_board", schema = "web_db"): t_jpa_board 테이블과 매핑된다

- PK 설정

 @Id: 엔티티의 PK(기본키) 임을 내타냄
 @GeneratedValue(strategy = GenerationType.AUTO): 기본키 생성 전략 설정. (JPA지원)

 @GeneratedValue(strategy = GenerationType.IDENTITY): 디비 방식(MySql방식따름) ** 이것선택(아니면 에러가ㅜㅜ)

 

- 컬럼 설정
@Column(name="디비에 생성될컬럼명", nullable = false): 컬럼에 Not Null 속성


- 컬럼에 기본값

@ColumnDefault("0")
@ColumnDefault("'admin'")

이건 테이블 생성시 default 값으로 스크립트에 적힌다.

  예) creator_id varchar(255) default 'admin',

디폴트값 적용할려면 

   1. Entity에 @DynamicInsert, @DynamicUpdate 붙인다

     (null인 값의 컬럼은 insert, update 쿼리에서 빠지게해 디비자체의 default 속성이 적용되게 한다)

   2. 해당 컬럼에 @Column(nullable = false) 속성을 쓰지 않는다. 

      그리고 디비에서도 not null 속성이 있는지 확인 꼭 한다.

 

- JPA 관계 설정하기(1:M, M:1, 1:1 / 양방향설정,단방향설정)
@OneToMany : 1:N 관계를 표현하는 JPA 어노테이션

      하나의 게시글은 첨부파일이 없거나 1개 이상의 첨부파일을 가질수 있다.
@JoinColumn(name="BOARD_IDX") : 릴레이션 관계가 있는 테이블의 컬럼을 지정

 

- JPA 복합키를 사용하는 2가지 방법 

 1) @Embeddable 이용하는 방법( 객체지향 방식에 가까움)
 2) @IdClass 이용하는 방법 (DB방식에 가까움)

 

- JPA 복합키 중 중첩된 fk(foreign-key) 로 jpa로 설정

이건 양방향 + 복합키 사용 + 알파(중첩설정 관련) 이다.

@JoinColumnsOrFormulas 이용한다

예시는 아래에 ...

 

- 기타 롬복어노테이션
@Data: 롬복의 어노테이션으로 필드의 getter,setter를 생성하고 toString,hashCode,equals 메소드도 생성한다.setter의 경우 final이 선언되지 않은 필드에만 적용된다.

- 기타

 private LocalDateTime createdDatetime = LocalDateTime.now(); : 작성시간 초기값 설정,JPA의 디비에 독립적인 정점을 위해..

1) /entity/BoardEntity.java 생성

package board.board.entity;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Table(name="t_jpa_board", schema = "web_db")
@DynamicInsert
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class BoardEntity {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "board_idx")
	private Long boardIdx;
	
	@Column(nullable = false)
	private String title;
	
	@Column(nullable = false)
	private String contents;
	
	@Column(nullable = false)
	@ColumnDefault("0")
	private int hitCnt;
	
	//@Column(nullable = false)
	@Column  //ColumnDefault 처리가 될 경우, NotNull 옵션을 줄 수가 없었다. @Column(nullable=false)과 중복 적용이 되지 않는다.
	@ColumnDefault("'admin'")
	private String creatorId;
	
	@Column(nullable = false)
	private LocalDateTime createdDatetime = LocalDateTime.now();
	
	@Column
	@ColumnDefault("'admin'")
	private String updatedId;
	
	@Column
	private LocalDateTime updatedDatetime = LocalDateTime.now();
	
	@OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
	@JoinColumn(name="BOARD_IDX")
	//@OneToMany(mappedBy = "boardEntityFile",fetch=FetchType.EAGER, cascade = CascadeType.ALL)
	//@OneToMany(mappedBy = "boardEntityFile")
	private List<BoardFileEntity> fileList = new ArrayList<>();
	
}

 

2) /entity/BoardFileEntity.java 생성

package board.board.entity;

import java.io.Serializable;
import java.time.LocalDateTime;

import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/*
 * JPA 복합키를 사용하는 2가지 방법 
 * @Embeddable 이용하는 방법( 객체지향 방식에 가까움)
 * @IdClass 이용하는 방법 (DB방식에 가까움)
 */
@Entity
@Table(name="t_jpa_file", schema = "web_db")
//@IdClass(BoardFilePK.class)
@DynamicInsert
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class BoardFileEntity {
	
	
	/***
	//@IdClass(BoardFilePK.class) 이용시.. 
	//그런데 Cannot add foreign key constraint 문제로 @ManyToOne를 위해서 복합키는 사용하지 않았다
	@Id
	@Column(name="fileIdx")
	private int fileIdx;
	
	@Id
	@Column(name="boardIdx")
	private int boardIdx;
	****/
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long fileIdx;

	@Column(name="BOARD_IDX")
	private Long boardIdx;
	
    //이거는 /@ManyToOne 설정인데 여기에서는 단방향 부모->자식 방식으로 사용하였다
	//@ManyToOne(fetch = FetchType.LAZY)
	//@JoinColumn(name = "board_idx", nullable = false) 
	//private BoardEntity boardEntityFile;
	 
	@Column(nullable = false)
	private String originalFileName;
	
	@Column(nullable = false)
	private String storedFilePath;
	
	@Column(nullable = false)
	@ColumnDefault("0")
	private long fileSize;
	
	@ColumnDefault("'admin'")
	private String creatorId;
	
	@Column(nullable = false)
	private LocalDateTime createdDatetime = LocalDateTime.now();
	
	@ColumnDefault("'admin'")
	private String updatedId;
	
	private LocalDateTime updatedDatetime;
	
}

 

만약  JPA 복합키를 사용한다

/entity/BoardFilePK.java 생성

@AllArgsConstructor
@NoArgsConstructor
@Data
public class BoardFilePK implements Serializable{
	private int fileIdx;
	private int boardIdx;
}

 

** - JPA 복합키 중 중첩된 fk(foreign-key) 로 jpa로 설정 예시 -- ***

예)

 @ManyToOne
    @JoinColumnsOrFormulas(value = {
            @JoinColumnOrFormula(column =
            @JoinColumn(name = "shipment_plant_id",
                    referencedColumnName = "plant_id")),
            @JoinColumnOrFormula(formula =
            @JoinFormula(value = "brand_cd",
                    referencedColumnName = "brand_cd")),
    })
    private Plant shipmentPlant;

 

  @Column(name = "brand_cd", length = 10)
    private String brandCode;

  참고 ) 

https://medium.com/@SlackBeck/%EC%A4%91%EC%B2%A9%EB%90%9C-fk-foreign-key-%EB%A5%BC-jpa%EB%A1%9C-%EC%97%B0%EA%B4%80-%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-%ED%95%98%EA%B8%B0-216ba5f2b8ed

 

 

---- 위에 과정을 거치면 console에 이런 스크립트가 출력되면서 테이블이 자동 생성된다

create table t_jpa_file 
(file_idx bigint not null auto_increment, 
  board_idx integer, 
  created_datetime datetime(6) not null, 
  creator_id varchar(255) default 'admin', 
  file_size bigint default 0 not null, 
  original_file_name varchar(255) not null, 
  stored_file_path varchar(255) not null, 
  updated_datetime datetime(6), 
  updated_id varchar(255) default 'admin'
  , primary key (file_idx)
  ) engine=InnoDB

alter table t_jpa_file add constraint FK2nbe74xrl4gfj0wnqo1d6dk3l foreign key (board_idx) references t_jpa_board (board_idx)