상세 컨텐츠

본문 제목

JPA fk사용법 (@JoinColumn, @OneToMany(mappedBy="~"))

카테고리 없음

by shika 2022. 6. 2. 21:08

본문

오늘은 JPA에서의 fk에 대해서 알아보자

 

일단 fk값을 설정할떄는

fk에 해당하는 자바필드 위에 어노테이션으로

@ManyToOne 이나 @OneToMany를 붙혀준다

 

뒤에것을 기준으로 보면 편한데

@ManyToOne

pirvate User user; 라고 되어있으면

어노테이션뒤에있는 One이 user에 해당한다는 것이다.

 

즉 user가 1개일때 이클래스에 해당하는것은 여러개 필요하다는 뜻이겠죠?

 

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class Board {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) //auto_increment
	private int id;
	 
	@Column(nullable = false, length = 100)
	private String title;

	@Lob //대용량 데이터 필요할때 쓴다
	private String content; //섬머노트 라이브러리<html>태그가 섞여서 디자인이 됨.

	//@ColumnDefault("0") // 얘는 숫자이므로 default값안에 " "안에 ' '필요없다
	
	private int count; //조회수
	
	@ManyToOne(fetch = FetchType.EAGER)//fetchtype.eager은 기본전략임 //board가 many라는 뜻, user가 one 이라는 뜻 //뭔뜻이냐면 한명의 유저는 여러개의 board를 쓸 수 있다는 것이다
	@JoinColumn(name="userId")
	private User user; //글을 적은사람
	// 중요** :DB는 오브젝트를 저장할 수 없다.FK but 자바는 오브젝트를 저장할 수 있다
	//그래서 얘는 컬럼이 만들어질때 joincolumn의 userid라고 생성된다 그리고 연관관계는 유저객체가 fk로 만들어짐
	
	 // 어노테이션 joincolum필요없음!!!!! DB에서 하나의 칸안에는 하나의 값만 들어가야하므로
	//mappedBy 연관관계의 주인이 아니다(난 FK가 아니에요) DB에 컬럼을 만들지 마세요 //mappedBy에서 board는 Reply.java의 필드값을 적어주면된다.(name값아님! 자바필드값 board)
	@OneToMany(mappedBy = "board", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) //cascade는 board삭제할때 댓글까지 지워버리겠다는 뜻
	@JsonIgnoreProperties({"board"}) //jpa무한참조방지
	@OrderBy("id desc")
	 private List<Reply> replys;
	  
	@CreationTimestamp //현재시간 자동으로 들어감
	private Timestamp createDate;
}

이거를 살펴보도록 하자.

 

이제 주목할것은 일단 맨 처음 public class Board{} 위에 적혀진

 

@Entitiy 어노테이션이다.

이 어노테이션이 바로 JPA의 시작을 뜻하는 것이다.

 

이 클래스를 DB에서 테이블로 만들어줘~ 라는 뜻을 가지게 된다.

 

우리가 2번째로 주목해야할것은

@JoinColumn과 @OneToMany(mappedBy = "board", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE) 

이것이다

 

이것은 fk와 관련이 되어있는데

 

음 JoInColumn부터 먼저 말해보자면

실제 db에 User를 보면 User객체가 들어가는것이 아니고 

@JoinColumn(name="userId") 를 통해서

userId라는 fk가 생성되고 그것은 user의 id값인 int 값으로 들어가게 된다.

(fetch = FetchType.EAGER) 라는것은 EAGER과 LAZY가 있는데 

EAGER이라는 뜻은

이 클래스 즉 Board의 값을 들고올때 user의 정보도 바로 들고 오겠다는 뜻이다.

 

만약 내가 EAGER가 아닌 LAZY로 설정했다면

바로 값을 들고오는게 아닌 내가 들고오고싶을때 들고 오는 것이다.

 

오늘은 fk에 대해서 살펴보자면

그래JoinColumn이 써져있는것은 fk가 확실한데

 

위에 코드에서 replys를 보면 이것은 fk가 아니다.

@OneToMany(mappedBy = "board", fetch = FetchType.EAGER) 를 통해서

바로 값을 가져오기는 하지만 실제로 DB에 table을 생성할때는 생성되지 않는다는 뜻을 가지게 된다

왜냐?

 @JoinColumn이 없기 떄문이다/

 

그럼 저걸 왜 썼느냐?

자바 코드를 통해서 데이터를 불러올때 Reply의 정보를 들고오고 싶기 때문이다.

내가 Board를 들고올때 Reply의 정보를 불러오고 싶기 때문에

mappedBy = "board" 를 적어줘서 --> 난 fk가 아니에요 DB에는 컬럼을 만들지마세요 라는뜻

 

이고

 

테이블을 상상해보면 Board테이블에는 Reply에 대한 정보가 들어갈것이 없다

만약 연관관계를 지으려면 join을 하겠지?

 

쨋든 자바에서 정보를 들고 오기위해서 저렇게 작성한것이고

가장 중요하게

나는 정보를 들고오는 역할만 할께요 fk와는 아무관련 없어요!!!! 가

mappedBy 라는 말 속에 들어있는 것이다.

 

나머지는 차차 또 알아가보도록 하자.

아 그리고 mappedBy="board"는 

실제 Reply객체에 

@ManyToOne
@JoinColumn(name = "boardId")
private Board board;

이것이 있고

Board board의 이름을 가져와서 필드이름인 

board를 써준것이다.

(만약 private Board boardxxx123 이면 mappedBy = "boardxxx123" 이라고 쓰자)

 

그럼 오늘도 mappedBy의 뜻과

 

fk면 @JoinColumn + 원투메니or메니투원 등등을 쓴다는것을 꼭 기억하도록 하자..

댓글 영역