연관관계 매핑 - 다대일 매핑 (단반향)
web/JPA

연관관계 매핑 - 다대일 매핑 (단반향)

반응형

연관관계 매핑을 해야하는 경우가 많다. 예를 들어 학생을 가지고 학생에 소속 반을 찾거나 반을 사용해서 학생들을 찾거나 때가 있다.

 

양방향과 단방향 관계가 존재하는데 아래의 객체 형태를 보면 이해가 쉽다.

 

단방향

class Student {

 Class class;

}

 

class Class {}

 

양방향

class Student {

 Class class;

}

 

class Class {

 Student student;

}


이중에서 먼저 단방향 연관 관계에 대해 먼저 공부해보자.

 

단방향 연관관계

  • 학생과 반이있다.
  • 학생은 하나의 반에 소속된다.
  • 학생과 반은 다대일 관계이다. (학생이 , 반이 )
  • 학생 테이블을 담는 객체는 Student, 반 테이블을 담는 객체는 Classes를 사용한다.
  • 학생 테이블은 반 테이블의 키 CLASSES_ID를 외래키로 테이블과 연관 관계를 가진다.

 

학생 테이블이 다, 반 테이블이 일로 다대일 관계이기 때문에 Student 클래스에 포함된 Classes 객체에 다음과 같이 선언한다.


1
2
3
@ManyToOne
@JoinColumn(name="CLASSES_ID")
private Classes classes;
cs


@ManyToOne

- 다대일 관계라는 표현

 

 

@JoinColumn(name = "CLASSES_ID")

- 조인 컬럼은 외래키를 매핑할 때 사용한다. 이 어노테이션은 생략해도 된다.

- 만약 생략 할 경우 외래키는 다음과 규칙으로 찾는다. 필드명 + _ + 참조하는 테이블의 컬럼명 그래서 위에서는 생략할 경우 classes_CLASSES_ID의 형태의 외래키를 찾는다.


다대다 테이블 관계 매핑설정이 끝난 객체


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
32
package com.wedul.springboottest.student.dto;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
 
/**
 * springboottest
 *
 * @author wedul
 * @since 23/10/2018
 **/
@Table(name = "classes")
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Classes {
 
  @Id
  @Column(name = "CLASSES_ID")
  private String id;
 
  @Column(name = "name")
  private String name;
 
}
cs
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
32
33
package com.wedul.springboottest.student.dto;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.persistence.*;
 
/**
 * springboottest
 *
 * @author wedul
 * @since 23/10/2018
 **/
@Entity
@Table(name = "student")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
 
  @Id
  @Column(name = "STUDENT_ID")
  private String id;
 
  @Column(name = "name")
  private String name;
 
  @ManyToOne
  @JoinColumn(name = "CLASSES_ID")
  private Classes classes;
 
}
cs


삽입

그럼 이 다대다 관계를 이용해서 데이터를 넣어보자. entityManager를 데이터를 삽입하는 코드를 만들자

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
32
33
34
35
36
37
38
39
40
41
42
package com.wedul.springboottest.student.serviceImpl;
 
import com.wedul.springboottest.student.dto.Classes;
import com.wedul.springboottest.student.dto.Student;
import com.wedul.springboottest.student.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
 
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
 
/**
 * springboottest
 *
 * @author wedul
 * @since 23/10/2018
 **/
@Service
@Slf4j
public class StudentServiceImpl implements StudentService {
 
  @PersistenceContext
  private EntityManager entityManager;
 
  public StudentServiceImpl(EntityManager entityManager) {
    this.entityManager = entityManager;
  }
 
  @Override
  @Transactional
  public void insertStudent() {
    Classes classes1_1 = new Classes("1-1""1학년 1반");
    entityManager.persist(classes1_1);
 
    Student wedul = new Student("1-1-01""wedul", classes1_1);
    entityManager.persist(wedul);
 
    Student chul = new Student("1-1-02""chul", classes1_1);
    entityManager.persist(chul);
  }
}
cs


테스트 코드를 통해 테스트해보자.

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
package com.wedul.springboottest.member;
 
import com.wedul.springboottest.member.service.MemberService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
/**
 * springboottest
 *
 * @author wedul
 * @since 03/10/2018
 **/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest // rolleback 설정
public class MemberTest {
 
  @Autowired
  MemberService memberService;
 
  @Test
  public void jpa_test() {
    memberService.jpaService();
  }
 
}
 
cs


조회

1

2

3

4

5

6

@Override

@Transactional

public void selectStudent() {

  Student wedul = entityManager.find(Student.class"1-1-01");

  print(wedul);

}

Colored by Color Scripter

cs

 

출력 결과

아이디 : 1-1-02, 이름 : chul, 소속반: 1?? 1?

 

JPQL을 사용한 조회

1

2

3

4

5

6

7

8

9

 

  @Override

  @Transactional

  public void selectStudentWithJPQL() {

    String jpql = "select s from Student s join s.classes c where s.name=:studentName";

 

    Student student = entityManager.createQuery(jpql, Student.class).setParameter("studentName""chul").getSingleResult();

    print(student);

  }

Colored by Color Scripter

cs

 

 


연관관계제거


1

2

3

4

5

6

@Override

@Transactional

public void removeClasses() {

  Student wedul = entityManager.find(Student.class"1-1-01");

  wedul.setClasses(null);

}

Colored by Color Scripter


wedul 학생의 반 정보가 지워진것을 알 수 있다.


생각보다 어렵지 않다. 

반응형