Java와 DB는 패러다임이 다르다.
때문에 우리는 RDB의 테이블을 객체 형태로 다루기 위해 JPA(java 진영 표준 ORM)를 통해 테이블과 Entity를 매핑하여 사용한다.
즉, DB의 데이터를 객체지향적으로 다룰 수 있게 되는 것이다.
테이블 간의 연관관계를 객체에서는 어떻게 해석 할 지 알아보자
POST 테이블과 COMMENT 테이블이 1:N 으로 연관관계를 가지고 있다고 해보자
이 때 COMMENT 테이블이 POST_ID를 FK컬럼으로 가지고 join을 통해 서로를 참조할 수 있다
객체의 입장에서 바라보면 어떨까?
Comment가 필드로 PostId를 가지고 있으면 되지않을까?
해당 Comment의 Post를 조회 할 때 postId를 가지고 Post를 조회할 수 있다.
이는 데이터 지향적이지 객체지향적이라고 볼 수 없다
Comment가 필드로 Post를 가지고 참조하여 무언가를 할 수있도록 하기위해 우리는 맵핑을 해줘야한다.
@JoinColumn
외래키와 객체를 맵핑
Comment가 참조하고 있는 Post(객체)를 테이블 상에서 POST_ID(외래키)로 인식 할 수있도록 @JoinColumn 어노테이션을 사용하여 Comment.post와 COMMENT.POST_ID 를 맵핑 할 수 있다.
일반적이지는 않지만 OneToMany에서 단방향 맵핑을 할 경우 @JoinColumn 어노테이션을 사용하지 않는다면 맵핑테이블이 하나 더 생성된다.(OneToMany 단방향 에서 JoinColumn을 생략하면 JoinTable이 우선)
(그 반대는 JoinColumn 생략하면 아래에서 서술하는 referenced.. 기본설정으로 맵핑)
또한 One쪽에서 @JoinColumn을 사용하더라도 외래키는 Many쪽에 생기게 된다.
OneToMany 단방향설정을 하기 보다는 양방향 관계를 설정하자.
(mappedBy를 통해 주인 설정 해주지 않으면 맵핑테이블이 추가생성된다)
(주인은 외래키를 가지고 있는 쪽으로 정해주자)
JPA - One To Many 단방향의 문제점 - https://dublin-java.tistory.com/51
OneToOne 에서 JoinColumn을 생략할 시 양방향일 때는 모두 fk를 갖게 되고 단방향일 때는 생략해도 무방하겠다. 양방향 일 때는 mappedBy를 통해 주인을 정해주자
주요 속성
@OneToMany, ManyToOne, ...
@JoinColumn 만으로는 맵핑을 완료할 수 없다.
@Entity 클래스 안에서 필드로 객체를 선언하면 컴파일 에러가 발생한다.
객체 간 어떤 연관관계를 가지고 있는지 모르기 때문이다.
연관관계, 방향설정 너무나 자세히 설명되어있는 블로그
https://jeong-pro.tistory.com/231
https://ttl-blog.tistory.com/129#%F0%9F%90%B3%20mappedBy%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80%20%EC%95%8A%EC%9C%BC%EB%A9%B4...-2
val post = postRepository.findByIdOrNull(postId) ?: throw CustomException("post", ErrorCode.MODEL_NOT_FOUND)
val user = userRepository.findByIdOrNull(userPrincipal.id) ?: throw CustomException("user", ErrorCode.MODEL_NOT_FOUND)
println(post.commentList.size)
var comment = Comment(
content = commentRequest.content,
author = user.userName,
user = user,
post = post
)
println(post.commentList.size) // 이런식으로 사용할 수 있으니
commentRepository.save(comment)