Hibernate、一対多の関連関係
6563 ワード
データ・オブジェクト間の3つの関連付け:
一対一で、
1対多で、
多対多.
一対一の関連関係は,前編では既に述べたが,この一編は一対多にすぎない.
次に、顧客(Customer)と注文(Order)を例に挙げます.これは典型的な一対多のケースです.
なぜなら、各顧客は複数の注文を持つことができ、各注文は唯一の顧客に属しているからだ.
Customer.hbm.xml
Order.hbm.xml
Customer.java
test.java
また、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
一対一で、
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