본문 바로가기
개발/JPA

[JPA] @OneToOne 사용하기

by 코딩하는 흰둥이 2024. 11. 16.

@OneToMany , @ManyToOne 은 이전글을 참고하길 바란다

https://greed-yb.tistory.com/317

 

[JPA] @OneToMany , @ManyToOne 사용하기

TEST 용 SQL-- 학교의 반CREATE TABLE CLASS ( CLASS_ID BIGINT PRIMARY KEY IDENTITY , CLASS_NAME VARCHAR(50) NOT NULL);-- 반에 속해있는 학생들CREATE TABLE STUDENT ( STUDENT_ID BIGINT PRIMARY KEY IDENTITY , STUDENT_NAME VARCHAR(50) NOT NULL, CLAS

greed-yb.tistory.com

 

 

 

 

TEST 용 SQL
-- 학생 테이블
CREATE TABLE STUDENT (
    STUDENT_ID 			BIGINT PRIMARY KEY IDENTITY ,
    STUDENT_NAME 		VARCHAR(50) NOT NULL,
    CLASS_ID 			BIGINT ,
    FOREIGN KEY (CLASS_ID) REFERENCES CLASS(CLASS_ID)
);



-- 학생 프로필 정보 테이블
CREATE TABLE STUDENT_PROFILE (
    STUDENT_ID 			BIGINT PRIMARY KEY ,
    STUDENT_NAME 		VARCHAR(50) NOT NULL,
    STUDENT_KEY			BIGINT NOT NULL,
    STUDENT_AGE			BIGINT NOT NULL,
    STUDENT_ADDR		VARCHAR(50) NOT NULL
    FOREIGN KEY (STUDENT_ID) REFERENCES STUDENT(STUDENT_ID)
);




INSERT INTO STUDENT_PROFILE(STUDENT_ID , STUDENT_NAME , STUDENT_KEY , STUDENT_AGE,  STUDENT_ADDR)
VALUES(1 , '서준' , 110 , 9 , '서울시.....')

 

학생 프로필 정보 테이블에서 외래키(FK) 를 설정하였다

 

 

 

 

 

@OneToOne 에서는 1:1 관계로

서로 하나의 Entity 를 갖게 된다

예) 한명의 학생은 하나의 프로필 정보를 갖고 있다

 

 

 

@OneToOne - 양방향 설정하기
@Data
@Entity
@Table(name = "STUDENT")
public class StudentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long student_id;

    @Column(nullable = false)
    private String student_name;


    // 이전글에서 했던 ManyToOne
    @ManyToOne(fetch = FetchType.EAGER)
    // name 에는 studenet table 에서 사용하려는 외래키 컬럼 을 지정한다
    // referencedColumnName 에는 join 하려는 외래키 대상 table 컬럼 을 지정한다
    @JoinColumn(name = "class_id" , referencedColumnName = "class_id")
    private ClassEntity classEntity;
    ////////////////////////////////////////////////////////////////////

    // join 하려는 상대 Entity 에서 명한 StudentProfile Entity class 명
    @OneToOne(mappedBy = "studentEntity", cascade = CascadeType.ALL)
    private StudentProfile studentProfile;

}

 

학생 테이블학생 프로필 테이블을 연결한다(@OneToOne)

외래키(FK) 는 학생 프로필 테이블에 설정하였으니

Student Entity 에서는 mappedBy 를 설정한다

 

@Data
@Entity
@Table(name = "STUDENT_PROFILE")
public class StudentProfile {

    @Id
    private Long Student_id;

    @Column(nullable = false)
    private String Student_name;

    @Column(nullable = false)
    private Long Student_key;

    @Column(nullable = false)
    private Long Student_age;

    @Column(nullable = false)
    private String Student_addr;


    @OneToOne
    // name 에는 studenet table 에서 사용하려는 외래키 컬럼 을 지정한다
    // referencedColumnName 에는 join 하려는 외래키 대상 table 컬럼 을 지정한다
    @JoinColumn(name="student_id", referencedColumnName = "student_id")
    private StudentEntity studentEntity;
    
}

 

양방향이기 때문에 @OneToOne 을 설정한다

StudentProfile Entity 에서는 외래키(FK) 가 있기 때문에

@JoinColumn 을 설정한다

 

 

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/*")
public class JoinTestController {

    @Autowired
    private StundentRepository stundentRepository;

    @GetMapping("/joinTest")
    public void joinTest() throws Exception{

        // 학생 Id 가 1번인 학생의 정보
        Optional<StudentEntity> studentOpt = stundentRepository.findById(1L);
        // 데이터가 존재한다면
        if (studentOpt.isPresent()) {
            StudentEntity student = studentOpt.get();
            StudentProfile profile = student.getStudentProfile();

            System.err.println("====== 학생 ID 1번 프로필 ======");
            System.err.println("학생 ID : " + profile.getStudent_id());
            System.err.println("이름 : " + profile.getStudent_name());
            System.err.println("나이 : " + profile.getStudent_age());
            System.err.println("키 : " + profile.getStudent_key());
            System.err.println("주소 : " + profile.getStudent_addr());
        } else {
            System.err.println("학생을 찾을 수 없습니다.");
        }
    }
    
}

 

profile.toString() 으로 데이터를 가져오려니 양방향 설정으로 인하여

각각의 Entity 를 무한재귀로 가져오면서 오류가 발생하여 각각 선언해 주었다

 

 

 

 

 

 

 


 

 

 

 

@OneToOne - 단방향 설정하기

 

@Data
@Entity
@Table(name = "STUDENT")
public class StudentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long student_id;

    @Column(nullable = false)
    private String student_name;


    @ManyToOne(fetch = FetchType.EAGER)
    // name 에는 studenet table 에서 사용하려는 외래키 컬럼 을 지정한다
    // referencedColumnName 에는 join 하려는 외래키 대상 table 컬럼 을 지정한다
    @JoinColumn(name = "class_id" , referencedColumnName = "class_id")
    private ClassEntity classEntity;


    // join 하려는 상대 Entity 의 FK 설정
    @OneToOne
    @JoinColumn(name = "student_id")
    private StudentProfile studentProfile;

}

 

 

@OneToOne 에 설정했던 mappedBy 가 제외되고

 Join 대상의 외래키(FK) 를 설정한다

 

 

@Data
@Entity
@Table(name = "STUDENT_PROFILE")
public class StudentProfile {

    @Id
    private Long Student_id;

    @Column(nullable = false)
    private String Student_name;

    @Column(nullable = false)
    private Long Student_key;

    @Column(nullable = false)
    private Long Student_age;

    @Column(nullable = false)
    private String Student_addr;


}

 

 

단방향이기 때문에

설정하였던  @OneToOne@JoinColumn 을 적용하지 않는다

 

 

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/*")
public class JoinTestController {

    @Autowired
    private StundentRepository stundentRepository;

    @GetMapping("/joinTest")
    public void joinTest() throws Exception{

        // 학생 Id 가 1번인 학생의 정보
        Optional<StudentEntity> studentOpt = stundentRepository.findById(1L);
        // 데이터가 존재한다면
        if (studentOpt.isPresent()) {
            StudentEntity student = studentOpt.get();
            StudentProfile profile = student.getStudentProfile();

            System.err.println("====== 학생 ID 1번 프로필 ======");
            System.err.println(profile.toString());
        } else {
            System.err.println("학생을 찾을 수 없습니다.");
        }
    }
}

 

 

 

 

 

 

 


 

양방향

각각의 Entity 에 @OneToOne 를 설정하고

외래키(FK) 를 가지고 있는 Entity 에 @JoinColumn 을 설정한다

 

 

 

 

단방향

한쪽의 Entity 에만 @OneToOne@JoinColumn 에 외래키(FK) 를 설정한다

'개발 > JPA' 카테고리의 다른 글

[JPA] Query Log 설정하기  (0) 2024.11.17
[JPA] @OneToMany , @ManyToOne 사용하기  (1) 2024.11.15
[JPA] @GeneratedValue 사용하기  (0) 2024.11.14
[JPA] Entity 설정하기  (0) 2024.11.13
[JPA] DELETE 하기(Delete , DeleteById , DeleteAll)  (0) 2024.11.12

댓글