Many-to-many relationships occur when each record in an entity may have
many linked records in another entity and vice-versa.

このチュートリアルでは、HibernateでXMLマッピングファイル(hbm)を使用して多対多のテーブル関係を操作する方法を説明します。

このチュートリアルで使用されるツールとテクノロジ:

  1. Hibernate 3.6.3.Final

  2. MySQL 5.1.15

  3. Maven 3.0.3

  4. Eclipse 3.6

プロジェクト構造

このチュートリアルのプロジェクト構造。


多対多のプロジェクトフォルダ、title = "多対多プロジェクトフォルダ"、width = 471、高さ= 465

プロジェクトの依存関係

JBossリポジトリから最新の

hibernate.jar

を入手してください。


File:pom.xml

<project ...>

    <repositories>
        <repository>
            <id>JBoss repository</id>
            <url>http://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <dependencies>

        <!-- MySQL database driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.15</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.3.Final</version>
        </dependency>

        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>

    </dependencies>
</project>

1.「多対多」の例

これは多対多リレーションシップテーブル設計であり、STOCKテーブルには複数のCATEGORYがあり、CATEGORYは複数のSTOCKに属することができます。この関係はSTOCK__CATEGORYという3番目のテーブルにリンクされています。

表STOCK__CATEGORYは、2つの主キーと、STOCKおよびCATEGORYへの外部キー参照で構成されています。


多対多ER図、タイトル= "多対多図"、幅= 640、高さ= 193


MySQLテーブルスクリプト

CREATE TABLE `stock` (
  `STOCK__ID` int(10) unsigned NOT NULL AUTO__INCREMENT,
  `STOCK__CODE` varchar(10) NOT NULL,
  `STOCK__NAME` varchar(20) NOT NULL,
  PRIMARY KEY (`STOCK__ID`) USING BTREE,
  UNIQUE KEY `UNI__STOCK__NAME` (`STOCK__NAME`),
  UNIQUE KEY `UNI__STOCK__ID` (`STOCK__CODE`) USING BTREE
)

CREATE TABLE `category` (
  `CATEGORY__ID` int(10) unsigned NOT NULL AUTO__INCREMENT,
  `NAME` varchar(10) NOT NULL,
  `DESC` varchar(255) NOT NULL,
  PRIMARY KEY (`CATEGORY__ID`) USING BTREE
)

CREATE TABLE  `stock__category` (
  `STOCK__ID` int(10) unsigned NOT NULL,
  `CATEGORY__ID` int(10) unsigned NOT NULL,
  PRIMARY KEY (`STOCK__ID`,`CATEGORY__ID`),
  CONSTRAINT `FK__CATEGORY__ID` FOREIGN KEY (`CATEGORY__ID`) REFERENCES `category` (`CATEGORY__ID`),
  CONSTRAINT `FK__STOCK__ID` FOREIGN KEY (`STOCK__ID`) REFERENCES `stock` (`STOCK__ID`)
)

2. Hibernateモデルクラス

上記の表を表す

Stock.java`と

Category.java`の2つのモデルクラスを作成します。テーブル ‘

stock__category

‘に余分なクラスを作成する必要はありません。


File:Stock.java

package com.mkyong.stock;

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

public class Stock implements java.io.Serializable {

    private Integer stockId;
    private String stockCode;
    private String stockName;
    private Set<Category> categories = new HashSet<Category>(0);

   //getter, setter and constructor
}


File:Category.java

package com.mkyong.stock;

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

public class Category implements java.io.Serializable {

    private Integer categoryId;
    private String name;
    private String desc;
    private Set<Stock> stocks = new HashSet<Stock>(0);

   //getter, setter and constructor
}

3. Hibernate XMLマッピング

今度は、2つのHibernateマッピングファイル(hbm) –

Stock.hbm.xml`と

Category.hbm.xml`を作成してください。 3番目の ‘

stock__category

‘テーブルが ”

many-to-many

“タグを介した参照であることに気づくでしょう。


File:Stock.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.mkyong.stock.Stock" table="stock" catalog="mkyongdb">
        <id name="stockId" type="java.lang.Integer">
            <column name="STOCK__ID"/>
            <generator class="identity"/>
        </id>
        <property name="stockCode" type="string">
            <column name="STOCK__CODE" length="10" not-null="true" unique="true"/>
        </property>
        <property name="stockName" type="string">
            <column name="STOCK__NAME" length="20" not-null="true" unique="true"/>
        </property>
        <set name="categories" table="stock__category"
            inverse="false" lazy="true" fetch="select" cascade="all" >
            <key>
                <column name="STOCK__ID" not-null="true"/>
            </key>
            <many-to-many entity-name="com.mkyong.stock.Category">
                <column name="CATEGORY__ID" not-null="true"/>
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>


File:Category.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.mkyong.stock.Category" table="category" catalog="mkyongdb">
        <id name="categoryId" type="java.lang.Integer">
            <column name="CATEGORY__ID"/>
            <generator class="identity"/>
        </id>
        <property name="name" type="string">
            <column name="NAME" length="10" not-null="true"/>
        </property>
        <property name="desc" type="string">
            <column name="[DESC]" not-null="true"/>
        </property>
        <set name="stocks" table="stock__category" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="CATEGORY__ID" not-null="true"/>
            </key>
            <many-to-many entity-name="com.mkyong.stock.Stock">
                <column name="STOCK__ID" not-null="true"/>
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>

4.ハイバネート設定ファイル

次に、

Stock.hbm.xml`と

Category.hbm.xml`とMySQLの詳細を `hibernate.cfg.xml`に入れます。


File:hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.driver__class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyongdb</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">password</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="show__sql">true</property>
    <property name="format__sql">true</property>
    <mapping resource="com/mkyong/stock/Stock.hbm.xml"/>
    <mapping resource="com/mkyong/stock/Category.hbm.xml"/>
</session-factory>
</hibernate-configuration>

5.それを実行する

これを実行すると、HibernateはSTOCKテーブルにレコードを挿入し、2つのレコードをCATEGORYテーブルに追加し、2つのレコードをSTOCKに追加します)CATEGORYテーブル。


File:App.java

package com.mkyong;

import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import com.mkyong.stock.Category;
import com.mkyong.stock.Stock;
import com.mkyong.util.HibernateUtil;

public class App {
    public static void main(String[]args) {

        System.out.println("Hibernate many to many (XML Mapping)");
    Session session = HibernateUtil.getSessionFactory().openSession();

    session.beginTransaction();

    Stock stock = new Stock();
        stock.setStockCode("7052");
        stock.setStockName("PADINI");

        Category category1 = new Category("CONSUMER", "CONSUMER COMPANY");
        Category category2 = new Category("INVESTMENT", "INVESTMENT COMPANY");

        Set<Category> categories = new HashSet<Category>();
        categories.add(category1);
        categories.add(category2);

        stock.setCategories(categories);

        session.save(stock);

    session.getTransaction().commit();
    System.out.println("Done");
    }
}


Output …​結果は自明でなければならない

Hibernate many to many (XML Mapping)
Hibernate:
    insert
    into
        mkyongdb.stock
        (STOCK__CODE, STOCK__NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        mkyongdb.category
        (NAME, `DESC`)
    values
        (?, ?)
Hibernate:
    insert
    into
        mkyongdb.category
        (NAME, `DESC`)
    values
        (?, ?)
Hibernate:
    insert
    into
        stock__category
        (STOCK__ID, CATEGORY__ID)
    values
        (?, ?)
Hibernate:
    insert
    into
        stock__category
        (STOCK__ID, CATEGORY__ID)
    values
        (?, ?)
Done

  • Hibernateアノテーション** Hibernateアノテーションの多対多の場合は、//hibernate/hibernate-many-to-many-relationship-example-annotation/[example]のリンクを参照してください。

ダウンロードする –

Hibernate-many-to-many-xml-mapping.zip

(10KB)