일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- github 복제
- springboot
- api 개발
- 넘파이
- jar빌드
- 비밀번호 재설정 API
- 값 타입
- 스프링부트 OpenAI API
- Servlet
- MySQL
- git 충돌 해결
- JPA
- swap 메모리
- 파이썬
- JDBC
- 자바
- MVC
- 페이징 정렬
- HttpServletResponse
- 저장소 복제
- Git
- 스프링 이메일 전송
- 두수의 합 자바
- Chat GPT
- 프로그래머스
- 저장소 이전
- Json 객체
- JPQL
- 우분투
- 서버 배포
- Today
- Total
현의 개발 블로그
객체 지향적 개발 - 연관관계 매핑 본문
앞서 개발했던 대출 기능 관계를 살펴보자
BookService는 Book 객체를 가져오고, UserLoanHistoryRepository를 통해 검증 한다.
그 후 User를 가져와서, Book과 User를 UserLoanHistory에 저장한다.
이는 절차 지향적 프로그래밍이다.
User만 가져와서 대출 처리를 한다면 객체 지향적으로 바꿀 수 있다.
반납 기능도 살펴보자
기존에는 BookService가 User에서 유저 정보를 가져오고, UserLoanHistory에서 반납 처리를 했다.
User가 UserLoanHistory를 갖고 있고, BookService에서 User만 가져와 반납 처리를 하도록 바꿀 수 있다.
이처럼 대출과 반납 기능을 객체 지향적으로 프로그래밍하기 위해서는 User와 UserLoanHistory가 서로를 참조할 수 있어야 한다.
이 때 연관관계 매핑이 필요하다.
연관관계 매핑
public class UserLoanHistory {
@Id
@GeneratedValue
private Long id;
//private Long userId;
@ManyToOne(fetch = FetchType.LAZY)
private User user;
...
}
Long 타입에서 User 타입으로 변경한다.
그러면 오류가 발생하는데 user_loan_history에 user 필드가 없고, user_id만 있기 때문이다.
이 때 @ManyToOne을 붙이면 오류가 해결된다.
대출 기록은 여러개 이고, 대출 기록을 소유하는 사용자는 1명이다.
대출 기록 입장에서 N:1 관계이고, JPA에서는 N:1을 @ManyToOne으로 표시한다.
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany
private List<UserLoanHistory> userLoanHistories = new ArrayList<>();
...
}
User입장에서 대출 기록은 1:N 관계이므로, User에 대출 기록을 정의할 때 리스트를 사용한다.
JPA에서는 1:N은 @OneToMany로 표시한다.
연관관계 주인
이제 연관관계의 주인을 정해야 한다.
연관관계 주인은 table에서 누가 관계의 주도권을 가지고 있는지를 말한다.
user테이블과 user_loan_history 테이블을 살펴보자.
user_loan_history는 user를 알고 있다. 반면 user는 user_loan_history를 알지 못한다.
따라서 user_loan_history가 관계의 주도권을 가지기 때문에 연관관계 주인이다.
연관관계 주인의 반대편에 mappBy 옵션을 줘야 한다.
들어갈 값은 연관관계 주인이 가진 필드 이름인 user이다.
mappBy를 작성하면, UserLoanHistory의 user 필드를 JPA가 연관관계 주인으로 인식한다.
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "user")
private List<UserLoanHistory> userLoanHistories = new ArrayList<>();
...
}
앞에서 UserLoanHistory의 user_id를 user로 변경하였기 때문에, 해당 생성자와 BookService 부분을 변경해야 한다.
마무리
두 객체간 연관관계 매핑을 하는 방법을 살펴보았다.
다음 글에서는 다양한 연관관계와 casecade, orphanRemoval 옵션에 대해 알아볼 것이다.
JPA 연관관계 매핑 보충 (Cascade, OrphanRemoval)
앞에서 객체 지향적 프로그래밍을 위해 연관관계 매핑이 필요하다고 말했었다. 그에 따라 UserLoanHistory와 User에 양방향 매핑을 해주었다. 이제 BookService부분을 고치기 전에 연관관계 매핑에 대해
hyun-keepdeving.tistory.com
참고
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인
Java와 Spring Boot, JPA, MySQL, AWS를 이용해 서버를 개발하고 배포합니다. 웹 애플리케이션을 개발하며 서버 개발에 필요한 배경지식과 이론, 다양한 기술들을 모두 학습할 뿐 아니라, 다양한 옵션들
www.inflearn.com
'스프링부트 실습 > 도서관리 웹 개발' 카테고리의 다른 글
책 관리 기능 리팩토링 (0) | 2023.04.19 |
---|---|
JPA 연관관계 매핑 보충 (Cascade, OrphanRemoval) (0) | 2023.04.19 |
JPA로 도서관리 API 개발하기 (0) | 2023.04.17 |
JPA 활용한 User CRUD 개발 (0) | 2023.04.17 |
JDBC를 활용해 API 개발하기3 - 역할 분리 (0) | 2023.04.15 |