映射一对多关联关系
以Customer和Order为例:
一对多:
每个Customer可以有一个或者多个Order,因此Customer中应该有一个集合类型的属性,来引用所有关联的Order对象。
多对一:
Order到Customer的关联为多对一关联,每个Order对象都要有一个Customer对象。在Order中要有一个Customer类型的属性。
如果仅包含Customer到Order或者仅包含Order呆Customer的关联,就叫做单向关联。
同时包含两个关联的就坐双向关联。
第一部分:以Order和Customer为例,介绍如何映射多对一单向关联关系。
这个例子的特点是只在Order中加入Customer属性,建立单向关联。
1 数据库:
alter table ORDERS drop foreign key FK8B7256E516B4891C;
drop table if exists CUSTOMERS;
drop table if exists ORDERS;
create table CUSTOMERS (
ID bigint not null,
NAME varchar(15),
primary key (ID)
);
create table ORDERS (
ID bigint not null,
ORDER_NUMBER varchar(15),
CUSTOMER_ID bigint not null,
primary key (ID)
);
alter table ORDERS add index FK8B7256E516B4891C (CUSTOMER_ID), add constraint FK8B7256E516B4891C foreign key (CUSTOMER_ID) references CUSTOMERS (ID);
2 类
Customers.java
package mypack;
import java.util.HashSet;
import java.util.Set;
/**
*CustomersgeneratedbyMyEclipsePersistenceTools
*/
publicclass Customers implements java.io.Serializable {
// Fields
private Long id;
private String name;
// Constructors
/**defaultconstructor*/
public Customers() {
}
/**fullconstructor*/
public Customers(String name) {
this.name = name;
}
// Property accessors
public Long getId() {
returnthis.id;
}
publicvoid setId(Long id) {
this.id = id;
}
public String getName() {
returnthis.name;
}
publicvoid setName(String name) {
this.name = name;
}
}
Orders.java
package mypack;
/**
*OrdersgeneratedbyMyEclipsePersistenceTools
*/
publicclass Orders implements java.io.Serializable {
// Fields
private Long id;
private Customers customers;
private String orderNumber;
// Constructors
/**defaultconstructor*/
public Orders() {
}
/**minimalconstructor*/
public Orders(Customers customers) {
this.customers = customers;
}
/**fullconstructor*/
public Orders(Customers customers, String orderNumber) {
this.customers = customers;
this.orderNumber = orderNumber;
}
// Property accessors
public Long getId() {
returnthis.id;
}
publicvoid setId(Long id) {
this.id = id;
}
public Customers getCustomers() {
returnthis.customers;
}
publicvoid setCustomers(Customers customers) {
this.customers = customers;
}
public String getOrderNumber() {
returnthis.orderNumber;
}
publicvoid setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
}
测试类:
BusinessService.java
package mypack;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.sun.org.apache.xpath.internal.operations.Or;
import sessionFactory.HibernateSessionFactory;
publicclass BusinessService {
public List findOrdersByCustomer(Customers customer) throws Exception {
Session session = null;
Transaction tr = null;
try {
session = HibernateSessionFactory.getSession();
tr = session.beginTransaction();
Query query = session
.createQuery("from Orders as o where o.customers.id="
+ customer.getId());
List orders = query.list();
tr.commit();
return orders;
} catch (Exception e) {
// TODO: handle exception
if (tr != null) {
tr.rollback();
}
throw e;
} finally {
session.close();
}
}
public Customers findCustomer(Long customer_id) throws Exception {
Session session = null;
Transaction tr = null;
try {
session = HibernateSessionFactory.getSession();
tr = session.beginTransaction();
Customers customer = (Customers) session.load(Customers.class,
customer_id);
tr.commit();
return customer;
} catch (Exception e) {
// TODO: handle exception
if (tr != null) {
tr.rollback();
}
throw e;
} finally {
session.close();
}
}
publicvoid saveCustomerAndOrder() throws Exception {
Session session = null;
Transaction tr = null;
try {
session = HibernateSessionFactory.getSession();
tr = session.beginTransaction();
Customers customer = new Customers("zhang");
session.save(customer);
Orders order1 = new Orders(customer, "order1");
Orders order2 = new Orders(customer, "order2");
session.save(order1);
session.save(order2);
tr.commit();
} catch (Exception e) {
// TODO: handle exception
if (tr != null) {
tr.rollback();
}
throw e;
} finally {
session.close();
}
}
publicvoid saveCustomerAndOrdeWithCascader() throws Exception {
Session session = null;
Transaction tr = null;
try {
session = HibernateSessionFactory.getSession();
tr = session.beginTransaction();
Customers customer = new Customers("zhang");
// session.save(customer);//映射文件中加入cascade="save-update"
Orders order1 = new Orders(customer, "order1");
Orders order2 = new Orders(customer, "order2");
session.save(order1);
session.save(order2);
tr.commit();
} catch (Exception e) {
// TODO: handle exception
if (tr != null) {
tr.rollback();
}
throw e;
} finally {
session.close();
}
}
publicvoid printOrders(List orders) {
for (Iterator it = orders.iterator(); it.hasNext();) {
Orders order = (Orders) it.next();
System.out.println("OrderNumber of "
+ order.getCustomers().getName() + " :"
+ order.getOrderNumber());
}
}
publicvoid test() throws Exception {
saveCustomerAndOrder();
saveCustomerAndOrdeWithCascader();
Customers customer = findCustomer(new Long(1));
List orders = findOrdersByCustomer(customer);
printOrders(orders);
}
/**
*@paramargs
*@throwsException
*/
publicstaticvoid main(String[] args) throws Exception {
// TODO Auto-generated method stub
BusinessService b = new BusinessService();
b.test();
}
}
3 映射文件:
Customers.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="mypack.Customers" table="customers"
catalog="onetomany" lazy="false">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="increment" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="15" />
</property>
</class>
</hibernate-mapping>
Orders.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="mypack.Orders" table="orders" catalog="onetomany">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="increment" />
</id>
<many-to-one name="customers" class="mypack.Customers"
fetch="select" cascade="save-update">
<column name="CUSTOMER_ID" not-null="true" />
</many-to-one>
<property name="orderNumber" type="java.lang.String">
<column name="ORDER_NUMBER" length="15" />
</property>
</class>
</hibernate-mapping>
小结:本例子的重点是级联保存和更新的使用。当建立了Order到Customer的单向关联时,把映射文件中的<many-to-one>的cascade属性设置为save-update,只做保存Order的操作,与Order对应的customer对象就自动被保存了。(前提是在测试的文件中加入了对Order的Customer属性的设置)