A one-to-many relationship occurs when one entity is related to many
occurrences in another entity.

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

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

  1. Hibernate 3.6.3.Final

  2. MySQL 5.1.15

  3. Maven 3.0.3

  4. Eclipse 3.6

プロジェクト構造

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


1対多のフォルダ、title = "1対多関係フォルダ"、width = 490、height = 483

プロジェクトの依存関係

JBossリポジトリから

hibernate.jar

を取得すると、Mavenはあなたに関連するすべての依存関係に注意を払います


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.「1対多数」の例

これは

1対多

関係表の設計であり、STOCK表には多数のSTOCK

DAILY

RECORD表があります。


1対多のテーブル関係、title = "1対多関係"、width = 554、height = 207

MySQLのテーブルスクリプトを参照してください

DROP TABLE IF EXISTS `stock`;
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
) ENGINE=InnoDB AUTO__INCREMENT=34 DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `mkyongdb`.`stock__daily__record`;
CREATE TABLE  `mkyongdb`.`stock__daily__record` (
  `RECORD__ID` int(10) unsigned NOT NULL AUTO__INCREMENT,
  `PRICE__OPEN` float(6,2) DEFAULT NULL,
  `PRICE__CLOSE` float(6,2) DEFAULT NULL,
  `PRICE__CHANGE` float(6,2) DEFAULT NULL,
  `VOLUME` bigint(20) unsigned DEFAULT NULL,
  `DATE` date NOT NULL,
  `STOCK__ID` int(10) unsigned NOT NULL,
  PRIMARY KEY (`RECORD__ID`) USING BTREE,
  UNIQUE KEY `UNI__STOCK__DAILY__DATE` (`DATE`),
  KEY `FK__STOCK__TRANSACTION__STOCK__ID` (`STOCK__ID`),
  CONSTRAINT `FK__STOCK__TRANSACTION__STOCK__ID` FOREIGN KEY (`STOCK__ID`)
  REFERENCES `stock` (`STOCK__ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO__INCREMENT=36 DEFAULT CHARSET=utf8;

2. Hibernateモデルクラス

上記の表を表すために、

Stock.java`と

StockDailyRecord.java`という2つのモデルクラスを作成します。


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<StockDailyRecord> stockDailyRecords =
                new HashSet<StockDailyRecord>(0);

   //getter, setter and constructor
}


File:StockDailyRecord.java

package com.mkyong.stock;

import java.util.Date;

public class StockDailyRecord implements java.io.Serializable {

    private Integer recordId;
    private Stock stock;
    private Float priceOpen;
    private Float priceClose;
    private Float priceChange;
    private Long volume;
    private Date date;

   //getter, setter and constructor
}

3. Hibernate XMLマッピング

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

Stock.hbm.xml`と

StockDailyRecord.hbm.xml`を作成してください。


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="stockDailyRecords" table="stock__daily__record"
                inverse="true" lazy="true" fetch="select">
            <key>
                <column name="STOCK__ID" not-null="true"/>
            </key>
            <one-to-many class="com.mkyong.stock.StockDailyRecord"/>
        </set>
    </class>
</hibernate-mapping>


File:StockDailyRecord.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.StockDailyRecord" table="stock__daily__record"
        catalog="mkyongdb">
        <id name="recordId" type="java.lang.Integer">
            <column name="RECORD__ID"/>
            <generator class="identity"/>
        </id>
        <many-to-one name="stock" class="com.mkyong.stock.Stock" fetch="select">
            <column name="STOCK__ID" not-null="true"/>
        </many-to-one>
        <property name="priceOpen" type="java.lang.Float">
            <column name="PRICE__OPEN" precision="6"/>
        </property>
        <property name="priceClose" type="java.lang.Float">
            <column name="PRICE__CLOSE" precision="6"/>
        </property>
        <property name="priceChange" type="java.lang.Float">
            <column name="PRICE__CHANGE" precision="6"/>
        </property>
        <property name="volume" type="java.lang.Long">
            <column name="VOLUME"/>
        </property>
        <property name="date" type="date">
            <column name="DATE" length="10" not-null="true" unique="true"/>
        </property>
    </class>
</hibernate-mapping>

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

Hibernate設定ファイルに

Stock.hbm.xml`と

StockDailyRecord.hbm.xml`を置きます。また、MySQL接続の詳細も表示します。


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/StockDailyRecord.hbm.xml"/>
</session-factory>
</hibernate-configuration>

5.それを実行する

これを実行すると、HibernateはSTOCKテーブルに行を挿入し、STOCK

DAILY

RECORDテーブルに行を挿入します。


File:App.java

package com.mkyong;

import java.util.Date;

import org.hibernate.Session;

import com.mkyong.stock.Stock;
import com.mkyong.stock.StockDailyRecord;
import com.mkyong.util.HibernateUtil;

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

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

    session.beginTransaction();

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

        StockDailyRecord stockDailyRecords = new StockDailyRecord();
        stockDailyRecords.setPriceOpen(new Float("1.2"));
        stockDailyRecords.setPriceClose(new Float("1.1"));
        stockDailyRecords.setPriceChange(new Float("10.0"));
        stockDailyRecords.setVolume(3000000L);
        stockDailyRecords.setDate(new Date());

        stockDailyRecords.setStock(stock);
        stock.getStockDailyRecords().add(stockDailyRecords);

        session.save(stockDailyRecords);

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

__出力…​

Hibernate one to many (XML Mapping)
Hibernate:
    insert
    into
        mkyongdb.stock
        (STOCK__CODE, STOCK__NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        mkyongdb.stock__daily__record
        (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)

それをダウンロードする –

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

(10KB)

リファレンス

ドキュメンテーション – 1対多の関係。