Skip to content

Instantly share code, notes, and snippets.

@limjinsun
Last active September 2, 2018 03:21
Show Gist options
  • Select an option

  • Save limjinsun/742b67d3fde6b72e159b734563375209 to your computer and use it in GitHub Desktop.

Select an option

Save limjinsun/742b67d3fde6b72e159b734563375209 to your computer and use it in GitHub Desktop.

하이버네트에서 원투매니 릴레이션 세팅법

DROP SCHEMA IF EXISTS `hb-03-one-to-many`;

CREATE SCHEMA `hb-03-one-to-many`;

use `hb-03-one-to-many`;

SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `instructor_detail`;

CREATE TABLE `instructor_detail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `youtube_channel` varchar(128) DEFAULT NULL,
  `hobby` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;


DROP TABLE IF EXISTS `instructor`;

CREATE TABLE `instructor` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) DEFAULT NULL,
  `last_name` varchar(45) DEFAULT NULL,
  `email` varchar(45) DEFAULT NULL,
  `instructor_detail_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_DETAIL_idx` (`instructor_detail_id`),
  CONSTRAINT `FK_DETAIL` FOREIGN KEY (`instructor_detail_id`) REFERENCES `instructor_detail` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

DROP TABLE IF EXISTS `course`;

CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(128) DEFAULT NULL,
  `instructor_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `TITLE_UNIQUE` (`title`),
  KEY `FK_INSTRUCTOR_idx` (`instructor_id`),
  CONSTRAINT `FK_INSTRUCTOR` FOREIGN KEY (`instructor_id`) REFERENCES `instructor` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;


SET FOREIGN_KEY_CHECKS = 1;
mysql> SELECT * FROM course;
+----+---------+---------------+
| id | title   | instructor_id |
+----+---------+---------------+

mysql> SELECT * FROM instructor;
+----+------------+-----------+--------------------+----------------------+
| id | first_name | last_name | email              | instructor_detail_id |
+----+------------+-----------+--------------------+----------------------+

mysql> SELECT * FROM instructor_detail;
+----+------------------------+--------+
| id | youtube_channel        | hobby  |
+----+------------------------+--------+

이 SQL쿼리를 보면 instructor_detail 테이블에는 포린키가 없고, instructor 테이블에는 - instructor_detail 테이블로 포린키가 설정되어 있다. course 테이블에는 instructor 테이블로 포린키가 설정되어 있다.

그래서 요약하면

instructor 테이블

+------------+----------------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME          | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+----------------------+-----------------+-----------------------+------------------------+
| instructor | instructor_detail_id | FK_DETAIL       | instructor_detail     | id                     |
+------------+----------------------+-----------------+-----------------------+------------------------+
  • instructor_detail_id 컬럼에 포린키 설정됨 one to one
  • instructor_detail 테이블의 id 컬럼을 레퍼런스 함
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="instructor_detail_id") // instructor_detail_id 컬럼에 포린키 설정됨 one to one 
private InstructorDetail instructorDetail; // instructor_detail 테이블의 id 컬럼을 레퍼런스 함

course 테이블

+------------+---------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME   | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+---------------+-----------------+-----------------------+------------------------+
| course     | instructor_id | FK_INSTRUCTOR   | instructor            | id                     |
+------------+---------------+-----------------+-----------------------+------------------------+
  • instuctor_id 컬럼에 포린키 설정됨 many to one
  • instructor 테이블의 id 컬럼을 레퍼런스 함
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH}) 
@JoinColumn(name="instructor_id") // instuctor_id 컬럼에 포린키 설정됨 many to one
private Instructor instructor; // instructor 테이블의 id 컬럼을 레퍼런스 함

포린키가 각각 설정된 테이블에 @JoinColumn(name='')을적어줌과 동시에 @OneToOne 인지 @OneToMany 인지 적어주는것이 필요하다. 당연히 (name='') 섹션엔 해당컬럼 이름을 적어준다.

그리고 포린키를 받는편에서는 포린키를 만들어준 클래스의 객체를 선언해준 다음, @OneToMany(mappedBy="레퍼런스한 변수이름", cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH}) 으로 맵핑하여 연동될수 있게 해준다.One to Many 혹은 Many to One 릴레이션인 경우에 cascade = {} 에서는 cascadeType.delete 를 빼준다. 받는쪽 주는쪽 모두.

데이터 엔티티 클래스 셋업

@Entity
@Table(name="instructor")
public class Instructor {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private int id;

	@Column(name="first_name")
	private String firstName;

	@Column(name="last_name")
	private String lastName;

	@Column(name="email")
	private String email;

	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="instructor_detail_id")
	private InstructorDetail instructorDetail;
	
	@OneToMany(mappedBy="instructor", cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
	private List<Course> Courses;

	public Instructor() {

	}

	public Instructor(String firstName, String lastName, String email) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = email;
	}
}
@Entity
@Table(name="instructor_detail")
public class InstructorDetail {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private int id;

	@Column(name="youtube_channel")
	private String youtubeChannel;

	@Column(name="hobby")
	private String hobby;

	public InstructorDetail() {

	}
	
	@OneToOne(mappedBy="instructorDetail", cascade=CascadeType.ALL)
	private Instructor instructor;

	public InstructorDetail(String youtubeChannel, String hobby) {
		this.youtubeChannel = youtubeChannel;
		this.hobby = hobby;
	}
}
@Entity
@Table
public class Course {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id")
	private int id;
	
	@Column(name="title")
	private String title;
	
	@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
	@JoinColumn(name="instructor_id")
	private Instructor instructor;
	
	public Course() {
		// empty constructor
	}
	
	public Course(String title) {
		super();
		this.title = title;
	}
}

자료의 삽입과 삭제 방법

코드샘플

    public static void main(String[] args) {

		Session session = getFactory().openSession();
		Transaction transaction = null;
		
		Course tempCourse = new Course("Science");
		
		try {
			session.beginTransaction();
			
			int id = 1;
			Instructor instructor = session.get(Instructor.class, id);
			tempCourse.setInstructor(instructor);
			
			session.save(tempCourse);	

			transaction = session.getTransaction();
			transaction.commit();
		} catch (Exception e) { 
			if (transaction!=null) transaction.rollback(); 
			e.printStackTrace(); 
		} finally { 
			session.close();
		}

    }
    public static void main(String[] args) {

		Session session = getFactory().openSession();
		Transaction transaction = null;

		int theId = 11;
		Course tempCourse = session.get(Course.class, theId);

		try {
			session.beginTransaction();
			if (tempCourse != null) {
				session.delete(tempCourse);				
			}
			transaction = session.getTransaction();
			transaction.commit();
		} catch (Exception e) { 
			if (transaction!=null) transaction.rollback(); 
			e.printStackTrace(); 
		} finally { 
			session.close();
		}

	}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment