다대다(n:m) 관계 설정하기

Posted at 2009. 9. 2. 11:05 | Posted in Framework/Hibernate
반응형
이번에는 사람과 세미나 사이의 다대다(n:m) 관계를 설정해보겠습니다. ^^;;

사람은 여러개의 세미나를 등록할 수 있고, 세미나는 여러 사람이 올 수 있죠~

Java 1.6.0_15
Eclipse 3.5
Hibernate 3.3.2.GA
Apache Tomcat 6.0.18
MySQL 5.1 (HSQLDB 1.9.0 rc4)



사람(Person)과 세미나(Person) 을 매핑 합시다~

Person.java
package com.tistory.antop;

public class Person {

    private int seq;
    private String name;
    private Gender gender;
 
    private enum Gender {
        남, 여
    }
 
    // constructor, getter and setter (private setter seq)
}

Person.hbm.xml
<hibernate-mapping package="com.tistory.antop">
    <class name="Person" table="tbl_person">
        <id name="seq">
            <generator class="native" />
        </id>
  
        <property name="name" />
        <property name="gender" />
  
    </class>
</hibernate-mapping>


Seminar.java
package com.tistory.antop;

import java.util.Date;

public class Seminar {

    private int sid;
    private String title;
    private Date sDate = new Date();
    private String area;

    // constructor, getter and setter (private setter sid)
 }

Seminar.hbm.xml
<hibernate-mapping package="com.tistory.antop">
    <class name="Seminar" table="tbl_seminar">
        <id name="sid">
            <generator class="native" />
        </id>
  
        <property name="title" />
        <property name="sDate" column="s_date" />
        <property name="area" />
  
    </class>
</hibernate-mapping>


hibernate.cfg.xml
<hibernate-configuration>
    <session-factory>
        ...

        <!-- Mapping -->
        <mapping resource="com/tistory/antop/Person.hbm.xml" />
        <mapping resource="com/tistory/antop/Seminar.hbm.xml" />

    </session-factory>
</hibernate-configuration>


관계가 맺어지지 않은 테이블이 매핑 되었습니다~



이제 n:m 관계를 맺어봅시다~

논리적(생각)으로는 두 테이블이 n:m 관계가 나오지만, 물리적(실제)으로는 n:m 관계를 만들려면 두 테이블을 이어줄 테이블이 하나 더 껴들어가야 합니다... ㅠ_ㅠ




클래스와 매핑 XML 에 n:m 관계(양방향)를 추가 합시다.

서로를 n 개만큼 참조해야하므로 Set 으로 하겠습니다.


Person.java
package com.tistory.antop;

import java.util.HashSet;
import java.util.Set;

public class Person {
   
    ...

    // person n:m seminar
    private Set<Seminar> seminars = new HashSet<Seminar>();

    public Set<Seminar> getSeminars() {
        return seminars;
    }

    public void setSeminars(Set<Seminar> seminars) {
        this.seminars = seminars;
    }

    // 세미나 등록
    public void addSeminar(Seminar s) {
        this.seminars.add(s);
    }
    
    // 세미나 취소
    public void cancelSeminar(Seminar s) {
        this.seminars.remove(s);
    }
}

Person.hbm.xml
<hibernate-mapping package="com.tistory.antop">
    <class name="Person" table="tbl_persons">
        ...

        <!-- person n:m seminar -->
        <set name="seminars" table="tbl_persons_seminars">
            <key column="seq" />
            <many-to-many class="com.tistory.antop.Seminar" column="sid" />
        </set>
 
    </class>
</hibernate-mapping> 

<set name="seminars" table="tbl_persons_seminars">
   java.util.Set 을 사용 했고 담고있을 필드는 seminars, n:m 관계를 맺어주는 테이블명은 tbl_persons_seminars

<key column="seq" />
   자기 테이블(Person)의 FK(Foreign Key) 되는 칼럼명입니다.

<many-to-many class="com.tistory.antop.Seminar" column="sid"  />
  m 관계를 맺게되는 테이블(tbl_seminar)의 클래스명과 그쪽의 FK가 되는 칼럼명입니다.


Seminar 쪽도 마친가지로 매핑해 줍니다.

Seminar.java
package com.tistory.antop;

import java.util.HashSet;
import java.util.Set;

public class Seminar {

    // person n:m seminar
    private Set<Person> persons = new HashSet<Person>();

    // 누가 이 세미나에 신청 했는지 알기위해 getter 만 public
    public Set<Person> getPersons() {
        return persons;
    }

    @SuppressWarnings("unused")
    private void setPersons(Set<Person> persons) {
        this.persons = persons;
    }
 
    // 사람(person)이 세미나 등록, 취소를 할 수 있다고 보고 세미나를 기준으로 등록 삭제는 없슴!
}

Seminar.hbm.xml
<hibernate-mapping package="com.tistory.antop">
    <class name="Seminar" table="tbl_seminars">

        ...  

        <!-- person n:m seminar -->
        <set name="persons" table="tbl_persons_seminars">
            <key column="sid" />
            <many-to-many class="com.tistory.antop.Person" column="seq" />
        </set>
  
 </class>
</hibernate-mapping>




테스트 해봅시다~

request.getParameter() 안쓰려고 스트러츠 썻는데 더 꼬여뿌렀네용 -_-;;

하이버네이트 부분은 dao 에 있습니다.




반응형

'Framework > Hibernate' 카테고리의 다른 글

PK 두개 이상시 매핑  (2) 2009.12.24
Reverse Engineering  (0) 2009.12.24
Hibernate 시작하기  (0) 2009.12.23
Criteria 사용하여 질의 하기 #2  (1) 2009.10.03
Criteria 사용하여 질의 하기 #1  (4) 2009.09.10
일대다(1:n) 관계 설정하기  (1) 2009.08.31
일대일(1:1) 관계 설정하기  (0) 2009.08.27
하이버네이트(Hibernate) 사용하기  (6) 2009.08.24
//