'1-1'에 해당되는 글 1건

  1. 2010.06.04 Hibernate 1-1관계
관계에 따른 매핑 방법
  • 1-1 관계
  • n-1 관계
1-1 관계
세가지 방법
  1. 동일한 키값을 갖는 경우
  2. 한 테이블의 주요 키 값을 다른 테이블에서 외부 키로 참조하는 경우
  3. 조인 테이블을 이용하는 경우
동일한 키 값을 갖는 1-1 관계
주요키를 사용한 1-1연관의 예
public class Article { //연관의 부모가 되는 클래스
  private int id;
  private String title;
  private ArticleDetail detail;
}

public class ArticleDetail { //연관의 자식이 되는 클래스
  private int id;
  private Article article;
  private String content;
}
ArticleDetail은 Article이 없다면 존재할수 없지만,
Article이 삭제된다도 함께 삭제 되지 않는다.
<class name="Article" table="ARTICLE">
  <id name="id" column="ID">
    <generator class="identity" />
  </id>
  ...
  <one-to-one name="detail" class="ArticleDetail"
    cascade="save-update,delete" />
</class>
cascade속성, Article객체가 저장(수정)될때 1-1연관으로 설정한 detail객체도 함께 저장(수정)된다.
cascade속성을 명시하지 않으면 Article이 저장되어도 ArticleDetail은 저장되지 않는다.
save-update 로 명시하지 않은 경우 Article과 연관된 ArticleDetail  객체를 저장하기 위해서는 Session.save(), Session.update()
에 ArticleDetail객체를 전달해야함.

자식에서 부모로의 1-1연관
<class name="ArticleDetail" table="ARTICLE_DETAIL">
  <id name="id" column="ARTICLE_ID">
    <generator class="foreign">
      <param name="property">article</param>
    </gegerator>
  </id>
  <one-to-one name="article" class="Article" constrained="true" />
  ..
</class>
cascade대신 constrained 속성사용.
자식은 부모의 키값을 자신의 키 값으로 사용함. -> 식별자 생성기로 ' foreign'를 사용.
constrained="true"는 프로퍼티의 키값이 외부 키에 의해 제약받는것을 의미. -> "article" 프로퍼티의 키값을 ArticleDetail의 키값으로 사용한다는 뜻.

1-1 연관을 맺은후
Article article = new Article();
ArticleDetail detail = new ArticleDetail();
article.setDetail(detail);
detail.setArticle(detail);
..
session.save(article);
cascade 속성을 명시하지 않으면, Article객체가 저장될때 ArticleDetail은 저장되지 않는다.
Article만 읽어와도 ArtileDetail를 사용할수 있다.
Article article = (Article) session.get(Article.class, new Integer(10));
ArticleDetail detail = article.getArticleDetail();

cascade속성에 delete가 포함되어있다면 Article를 삭제하면  1-1관계를 맺고있는 ArticleDetail 도 삭제된다.
Article article = (Article) session.get(Article.class, new Integer(10));
session.delete(article);

위 코드는 다음같이 두개의 쿼리가 실행된다.
delete from ARTICLE_DETAIL where ARTICLE_ID = 10
delete from ARTICLE where ID = 10

외부 키를 사용한 1-1 관계
MEMBER와 MEMBER_DETAIL은 다른 키값을 가지는 대신
MEMBER는 외부 키를 이용해   MEMBER_DETAIL 과 1-1연관을 맺는다.
<class name="Member" table="MEMBER">
  <id name="id" coloumn="ID">
    <genrator class="identity" />
  </id>
  <property name="usernmae' column="USERNAME" />
  <many-to-one name="detail"
    class="MemberDetail"
    column="MEMBER_DETAILEID"
    unique="true"
    cascade="save-update, delete" />
</class>

<class name="MemberDetail" table="MEMBER_DETAIL">
  <id name="id" column="ID">
    <generator class="identity" />
  </id>
  ...
  <one-to-one name="member" class="Member" property-ref="detail" />
</class>
<many-to-one> 은  detail 프로퍼티가 MEMBER_ARTICLEID칼럼과 매핑되며 MEMBER_DETAILID 칼럼은 MemberDetail 클래스와 연관된다고 지정하고 있음.
MemberDetail 클래스는 MEMBER_DETAIL 테이블과 매핑되므로, 결국 MEMBER 테이블의 MEMBER_DETAILEID 칼럼은 MEMBER_DETAIL 테이블의  ID칼럼을 참조하게 된다.

Member 객체가 저장/삭제될때 MemberDetail  객체도 저장/삭제야 하므로 cascade 속성을 save-update, delete로 지정.
하나의 Member객체는 고유의 MemberDetail 객체와 연관되므로 unique 속성을  "true"로 지정.

조인 테이블을 이용한 1-1관계

DELIVERY_ORDER 테이블의 제약
DELIVERYID - DEVLIERY 테이블의 주요키로 참조하며, 이칼럼 자체는 주요키가 된다.
ORDERINFO - ORDER 테이블의 주요키를 외부 키로 참조하며 1-1연관의 의미를 지키기 위해 제약 조건을 갖는다.

DELIVERY  테이블에서 ORDER 테이블로의 관계가 1-1이므로 Deliver 클래스는 Order타입의 필드를 포함하게 된다.
public class Delivery {
  private Integer id;
  private Order order;
  ..
}

조인 테이블을 사용하여, 1-1관계를 명시한 경우
<class name="Delivery" table="DELIVERY">
  <id name="id" column="ID">....</id>
 
  <join table="DELIVERY_ORDER" optional="true"
    <key coulumn="DELIVERYID" />
    <many-to-one name="order"
      column="ORDERINFOID" not-null="true" unique="true" />
  </join>
</class>

<class name="Order" table="ORDERINFO">....</class>
<join> 태그의 table 속성은 조인 테이블의 이름을 명시.
<key> 태그의 column속성은 조인 테이블에서 Delivery  클래스와 연관된 칼럼을 명시. (DELIVERYID)
<many-to-one>은 Delivery 클래스에서  Order클래스로의 연관 정보를 입력.
1-1 관계를 유지하기위해 unique속성을 true로 지정.
사용은 다음과 같이.
Order order = new Order();
Delivery delivery = new Delivery();
delivery.setOrder(order);

session.save(order);
session.save(delivery);

미리 생성된 Order객체를 구한뒤, Delivery  객체와 연관지어 저장할수 있다.
Order order = session.get(Order.class, 10);
Delivery delivery = new Delivery();
delivery.setOrder(order);
session.save(delivery);

<many-to-one> 태그의 not-null속성을   true로 지정하였으므로, order 프로퍼티의 값을 지정하지 않고
delivery객체를 저장하면 제약조건 위반 에러가 발생한다.
Delivery delivery = new Delivery();
session.save(delivery); // not-null 제약조건위반

<join> 태그의 optional속성 값을  true 로 하며, <join>태그를 통해 연관된 프로퍼티의 값이 null이 아닌 경우에만
조인 테이블에 값을 저장한다.
저작자 표시
신고
Posted by 영겁회귀

티스토리 툴바