Hibernate、一対多の関連関係

6563 ワード

データ・オブジェクト間の3つの関連付け:
一対一で、
1対多で、
多対多.
一対一の関連関係は,前編では既に述べたが,この一編は一対多にすぎない.
次に、顧客(Customer)と注文(Order)を例に挙げます.これは典型的な一対多のケースです.
なぜなら、各顧客は複数の注文を持つことができ、各注文は唯一の顧客に属しているからだ.
mysql> desc customer;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(32) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

mysql> desc orders;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(4)       | NO   | PRI | NULL    | auto_increment |
| money    | double(10,2) | YES  |     | NULL    |                |
| customer | int(4)       | YES  | MUL | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

Customer.hbm.xml
<hibernate-mapping>
	<class name="PO.Customer" table="customer" catalog="test">
		<id name="id" type="int">
			<column name="id" />
			<generator class="identity" />
		</id>
		<property name="name" type="string">
			<column name="name" length="32" />
		</property>
		<!--  Customer Orders        -->
		<set name="orders" table="orders" cascade="all" inverse="true">
			<key column="customer" />
			<one-to-many class="PO.Order" />
		</set>
	</class>
</hibernate-mapping>

Order.hbm.xml
<hibernate-mapping>
	<class name="PO.Order" table="orders">
		<id name="id" type="int">
			<column name="id" />
			<generator class="identity" />
		</id>
		<property name="money" type="double">
			<column name="money" />
		</property>
		<many-to-one name="customer" class="PO.Customer" cascade="all"
			column="customer" />
	</class>
</hibernate-mapping>

Customer.java
package PO;

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

public class Customer implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<Order> orders = new HashSet<Order>();

	public Customer() {
	}

	public Customer(String name) {
		this.name = name;
	}

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<Order> getOrders() {
		return orders;
	}

	public void setOrders(Set<Order> orders) {
		this.orders = orders;
	}
}
Order.java
package PO;

public class Order implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	private Integer id;
	private Double money;
	private Customer customer;

	public Order() {
	}

	public Order(Double money) {
		this.setMoney(money);
	}

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Double getMoney() {
		return money;
	}

	public void setMoney(Double money) {
		this.money = money;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
}

test.java
package test;

import java.io.File;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import PO.Customer;
import PO.Order;

public class test {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws Exception {
		File file = new File("src/hibernate.cfg.xml");
		System.out.println("file path:" + file.getAbsolutePath());
		Configuration cfg = new Configuration().configure(file);
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();

		Customer customer = new Customer("customer");
		Integer id = (Integer) session.save(customer);
		System.out.println("save(customer) id:" + id);

		Order order1 = new Order(1.1);
		// PO            
		order1.setCustomer(customer);
		customer.getOrders().add(order1);
		Integer id1 = (Integer) session.save(order1);
		System.out.println("save(order1) id:" + id1);

		Order order2 = new Order(2.2);
		// PO            
		order1.setCustomer(customer);
		customer.getOrders().add(order2);
		Integer id2 = (Integer) session.save(order2);
		System.out.println("save(order2) id:" + id2);

		Customer new_customer = (Customer) session.get(Customer.class, id);
		if (new_customer != null) {
			System.out.println("id:" + new_customer.getId() + ",name:"
					+ new_customer.getName());
			for (Order tmp_order : new_customer.getOrders()) {
				System.out.println("id:" + tmp_order.getId() + ",money:"
						+ tmp_order.getMoney());
			}
		}
		Order new_order = (Order) session.get(Order.class, id1);
		if (new_order != null) {
			Customer tmp_customer = new_order.getCustomer();
			System.out.println("id:" + tmp_customer.getId() + ",name:"
					+ tmp_customer.getName());
			System.out.println("id:" + new_order.getId() + ",money:"
					+ new_order.getMoney());
		}
		session.delete(customer);
		// session.delete(order1);
		// session.delete(order2);
		tx.commit();
		session.close();
		System.out.println("done.");
	}
}
ここでは、顧客と注文の双方向関連が確立され、双方がカスケードされており、delete(order 1)も顧客およびorder 2を削除することができる.
また、Mysqlデータベーステーブルを作成する場合、オーダーテーブル(orders)をorder(キーワード?)と命名することはできません.それ以外の場合は、次のエラーが発生します.
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax 
Exception in thread "main"org.hibernate.exception.SQLGrammarException: could not execute statement