Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- jpa에러
- Error creating bean with name
- spring서버
- json
- 인텔리제이
- Unsatisfied dependency
- 최종 프로젝트
- 복합키
- github
- 빈생성안됨
- Filter
- json gson 차이
- JPA
- REST API 규칙
- git
- ERD 작성
- REST란
- jwt메서드
- 1차캐시
- 스프링부트오류
- @IdClass
- JPA주의사항
- Spring Spring boot 차이
- queryDSL
- 스프링 부트 공식 문서
- uncheck Exception
- jpa회원가입
- 스프링 부트 기능
- Q 클래스
- JoinColumn
Archives
- Today
- Total
Everyday Dev System
@OneToMany 단방향 본문
1대다 관계 말고는 일반적으로 외래키는 외래키의 주인이 DB에 갖고 있다.
1대다 관계에서 외래키의 주인이 외래키를 갖고 있지 않으니까 추가적인 update문이 발생한 것이다.
1대 N 관계 단방향
1대 N관계 에서는 1의 주인이 외래키의 주인이다.
외래키의 주인은 음식 Entity이지만, 실제 DB 테이블에는 외래키를 고객이 가지고 있는 형태이다.
외래키의 주인인 음식 Entity 외래키 필드이다.
Food가 1의 관계이기 때문에 고객 Entity를 여러명을 표현하기 위해서 Java Collection인 List 활
@OneToMany
@JoinColumn(name = "food_id")
private List<User> userList = new ArrayList<>();
@JoinColumn(name = "food_id")
private List<User> userList = new ArrayList<>();
1 대 N 단방향 관계에서는
N의 관계인 테이블이 User이기 때문에 외래키를 User 테이블에 놔야 한다.
그러므로, Food Entity에 food_id 칼럼을 기재하여 user Table에 food_id 컬럼이 생기도록 한다.
외래키의 주인은 Food 이지만 실제 테이블에 저장되는 것은 외래키의 주인인 Food가 아닌
상대 Entity인 User이다. 그러므로 상대 Entity의 외래키를 Food Entity가 잠시 저장하고 있는 것이다.
N 대 1 단방향 일 때는
실제 DB 테이블에 외래키를 갖는 Entity가 Food 본인이였기 때문에
Food가 외래키를 갖는 것이므로 아래와 같이 표현하는 것이 맞다.
@JoinColumn(name = "user_id") private User user;
1 대 N 단방향 관계에서는 update가 추가적으로 발생된다는 문제 한계점이 발생한다.
1 대 N 관계에서는 일반적으로 양방향 관계는 미존재
1 대 N 양방향을 JPA 자체에서 미지원
@OneToMany는 mappedBy 옵션 사용 가능
@ManyToOne는 mappedBy 옵션 사용 불가
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "food")
public class Food {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
@OneToMany
@JoinColumn(name = "food_id") // users 테이블에 food_id 컬럼
private List<User> userList = new ArrayList<>();
}
package com.sparta.jpaadvance.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
package com.sparta.jpaadvance.relation;
import com.sparta.jpaadvance.entity.Food;
import com.sparta.jpaadvance.entity.User;
import com.sparta.jpaadvance.repository.FoodRepository;
import com.sparta.jpaadvance.repository.UserRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@SpringBootTest
public class OneToManyTest {
@Autowired
UserRepository userRepository;
@Autowired
FoodRepository foodRepository;
@Test
@Rollback(value = false)
@DisplayName("1대N 단방향 테스트")
void test1() {
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("후라이드 치킨");
food.setPrice(15000);
food.getUserList().add(user); // 외래 키(연관 관계) 설정
food.getUserList().add(user2); // 외래 키(연관 관계) 설정
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
// 추가적인 UPDATE 쿼리 발생을 확인할 수 있습니다.
}
@Test
@DisplayName("1대N 조회 테스트")
void test2() {
Food food = foodRepository.findById(1L).orElseThrow(NullPointerException::new);
System.out.println("food.getName() = " + food.getName());
// 해당 음식을 주문한 고객 정보 조회
List<User> userList = food.getUserList();
for (User user : userList) {
System.out.println("user.getId() = " + user.getId());
System.out.println("user.getName() = " + user.getName());
}
}
중요한 코드 :
Food.java
@OneToMany
@JoinColumn(name="food_id")
private List<User> userList = new ArrayList<>();
OneToManyTest.java
User user = new User();
user.setName("Robbie");
User user2 = new User();
user2.setName("Robbert");
Food food = new Food();
food.setName("후라이드 치킨");
food.setPrice(15000);
food.getUserList().add(user); // 외래 키(연관 관계) 설정
food.getUserList().add(user2); // 외래 키(연관 관계) 설정
userRepository.save(user);
userRepository.save(user2);
foodRepository.save(food);
User 객체를 생성 -> Food 객체를 생성 -> Food 객체의 UserList 필드에 생성한 User 객체 설정
결과 :
1. 1 대 N 단방향 데이터 넣기
Hibernate SQL query :
1. 1 대 N 단방향 데이터 넣기
Hibernate:
/* insert for
com.sparta.jpaadvance.entity.User */insert
into
users (name)
values
(?)
Hibernate:
/* insert for
com.sparta.jpaadvance.entity.User */insert
into
users (name)
values
(?)
Hibernate:
/* insert for
com.sparta.jpaadvance.entity.Food */insert
into
food (name,price)
values
(?,?)
Hibernate:
update
users
set
food_id=?
where
id=?
Hibernate:
update
users
set
food_id=?
where
id=?
2. 1 대 N 단방향 데이터 조회
Hibernate:
select
f1_0.id,
f1_0.name,
f1_0.price
from
food f1_0
where
f1_0.id=?
food.getName() = 후라이드 치킨
Hibernate:
select
u1_0.food_id,
u1_0.id,
u1_0.name
from
users u1_0
where
u1_0.food_id=?
user.getId() = 1
user.getName() = Robbie
user.getId() = 2
user.getName() = Robbert
'내배캠 주요 학습 > Spring 숙련' 카테고리의 다른 글
@ManyToMany 양방향 관계 이해하기 (0) | 2023.06.21 |
---|---|
@ManyToMany 단방향 관계 이해하기 (0) | 2023.06.21 |
@ManyToOne 활용하기 (0) | 2023.06.21 |
@OneToOne 외래키 활용 (1) | 2023.06.21 |
Entity 연관관계 (0) | 2023.06.20 |