'oneandone'에 해당되는 글 1건
- 2015.12.07 :: hibernate(7)
개발관련/Spring
2015. 12. 7. 12:01
이번엔 join에 대해 알아보자. join은 1:1 맵핑, 1:m, m:n 아마도 이렇게 구성이 될것이다.
여기서는 1:1에 대해 알아보자.
객체는 person과 personDetail 두가지가 있다. 그럼 코드를 보자.
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | package com.zest.hibernate.chapter6.onetoonemapping; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; /** * * one to one * ex) person data table * person id : 1 *person name: aaaa *pdetail_fk :32768 이넘 * *person_detail *detailId_pk : 32768 이넘 *income:123456786 *job : adklja *zipcode : 20815 * *위에 '이넘' 두개가 1:1로 맵핑. */ @Entity public class Person { @Id @GeneratedValue private int personId; private String personName; /** * CascadeType의 종류에는 다음과 같은 것들이 있다. CascadeType.RESIST – 엔티티를 생성하고, 연관 엔티티를 추가하였을 때 persist() 를 수행하면 연관 엔티티도 함께 persist()가 수행된다. 만약 연관 엔티티가 DB에 등록된 키값을 가지고 있다면 detached entity passed to persist Exception이 발생한다. CascadeType.MERGE – 트랜잭션이 종료되고 detach 상태에서 연관 엔티티를 추가하거나 변경된 이후에 부모 엔티티가 merge()를 수행하게 되면 변경사항이 적용된다.(연관 엔티티의 추가 및 수정 모두 반영됨) CascadeType.REMOVE – 삭제 시 연관된 엔티티도 같이 삭제됨 CascadeType.DETACH – 부모 엔티티가 detach()를 수행하게 되면, 연관된 엔티티도 detach() 상태가 되어 변경사항이 반영되지 않는다. CascadeType.ALL – 모든 Cascade 적용 fetch 의 순위 두 개 있다 fetch=FetchType.EAGER: 실행 문 바로 꺼냈다 fetch=FetchType.LAZY: 쓸 때 비로소 꺼냈다 */ @OneToOne(cascade=CascadeType.ALL, fetch= FetchType.EAGER) @JoinColumn(name="pDetail_FK") private PersonDetail pDetail; public PersonDetail getpDetail() { return pDetail; } public void setpDetail(PersonDetail pDetail) { this.pDetail = pDetail; } public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } } | cs |
새로운 어노테이션이 등장한다. OneToOne 과 JoinColumn 이 추가 되었다.
OneToOne의 경우 외래키를 만들때 선언하는 어노테이션이다. Cascade속성과 Fetch 속성 두가지를 지원한다. JoinColumn은 외래키가 되는 Column의 실제 Column이름을 지정하는것이다. 그냥 테이블 생성시에는 @Column이라는 놈이랑 비슷하다고 생각하면된다. 그리고 중요한 것은 기본키가 되는 객체에 어노테이션을 선언한다는것이다.
그럼 personDetail을 만들어보자.
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 43 44 45 46 47 48 49 50 | package com.zest.hibernate.chapter6.onetoonemapping; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class PersonDetail { @Id @GeneratedValue @Column(name="detailId_PK") private int personDetailId; private String zipCode; private String job; private double income; public int getPersonDetailId() { return personDetailId; } public void setPersonDetailId(int personDetailId) { this.personDetailId = personDetailId; } public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public double getIncome() { return income; } public void setIncome(double income) { this.income = income; } } | 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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | package com.zest.hibernate.chapter6.onetoonemapping; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.Test; import com.zest.hibernate.chapter5.inheritancemapping.Module; import com.zest.hibernate.chapter5.inheritancemapping.Project; import com.zest.hibernate.chapter5.inheritancemapping.Task; public class OneToOneTest { @Test public void oneTest(){ AnnotationConfiguration config = new AnnotationConfiguration(); config.addAnnotatedClass(Person.class); config.addAnnotatedClass(PersonDetail.class); config.configure("hibernate.cfg.xml"); new SchemaExport(config).create(true, true); // 아래 두개의 구문은 객체를 트랜잭션을 컨트롤. SessionFactory factory = config.buildSessionFactory(); Session session = factory.getCurrentSession(); session.beginTransaction(); PersonDetail alexDetail = new PersonDetail(); alexDetail.setZipCode("20815"); alexDetail.setJob("Accountant"); alexDetail.setIncome(67245.56); Person alex = new Person(); alex.setPersonName("alex berry"); alex.setpDetail(alexDetail); session.save(alex); //session.save(alexdetail); 이건 안함. 카스케이드 라서 session.getTransaction().commit(); } } | cs |
결과는 다음과 같다.
1 2 3 | Hibernate: insert into TESTSCHEMA.PersonDetail (income, job, zipCode, detailId_PK) values (?, ?, ?, ?) Hibernate: insert into TESTSCHEMA.Person (pDetail_FK, personName, personId) values (?, ?, ?) | cs |
테이블 구조를 보자. Person의 테이블을 살펴보면 PersonId는 기본키이며 pDetail_FK는 외래키로 생성이 될것이다. 여기까지 OneAndOne 설명을 마친다.