投射一对多双向关联关系
本文转自:http://mba.shengwushibie.com/itbook/BookChapter.asp?id=4341
4.3.6 映射一对多双向关联关系
4.3.6 映射一对多双向关联关系
在电子商务应用中,经常会有这样的需求:根据给定的客户,得到该客户的所有订单;根据给定的订单,得到该订单的所属客户。对于这种双向关联的情况,在Hibernate应用中,也有人叫多对一双向关联,只是叫法不同而已,都是通过映射一对多双向关联关系来实现的。
不管是多对一单向关联还是(一对多)多对一双向关联,在关系型数据库中的表现方式都是一样的,均通过外键参照来实现如图4-18所示。
|
只是在持久化类与ORM映射文件中单向关联与双向关联存在一些区别而已,如图4-19所示。
|
持久化类Customer.java:
- package com.ORM;
- import java.io.Serializable;
- import java.util.*;
- public class Customer implements Serializable{
- private java.lang.Integer id; //ID号
- private java.lang.String cname; //客户姓名
- private java.lang.String bank; //银行账号
- private java.lang.String phone; //联系电话
- private Set orders = new HashSet(); //订单集合
- public Customer(){}
- //省略上述各属性的get/set方法对
- }
持久化类Orders.java:
- package com.ORM;
- import java.io.Serializable;
- public class Orders implements Serializable{
- private java.lang.Integer id; //ID号
- private java.lang.String orderno; //订单编号
- private java.lang.Double money; //订单金额
- private Customer customer; //订单的所属客户
- public Orders(){}
- //省略上述各属性的get/set方法对
- }
customer表与Customer类的ORM映射文件Customer.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' >
- <hibernate-mapping package='com.ORM'>
- <class name='Customer' table='customer'>
- <id name='id' column='ID' type='integer'>
- <generator class='identity'/>
- </id>
- <property name='cname' column='CNAME' type='string' />
- <property name='bank' column='BANK' type='string' />
|
orders表与Orders类的ORM映射文件Orders.hbm.xml:
|
(1)创建供测试用的TestBean.java。
- ……
- public void addCustomer(){
- Customer customer = new Customer();
- customer.setCname('张三');
- customer.setBank('123456789123456789');
- customer.setPhone('020-12345678');
- dao.addCustomer(customer);
- }
- public Customer loadCustomer(Integer id){
- return dao.loadCustomer(id);
- }
- public void addOrders(Customer customer){
- Orders order = new Orders();
- order.setOrderno(new Long(System.currentTimeMillis()).toString());
- order.setMoney(new Double(rnd.nextDouble()*10000));
- //将Customer与Orders实例进行双向关联
- order.setCustomer(customer);
- customer.getOrders().add(order);
- dao.addOrders(order);
- }
- public Orders loadOrders(Integer id){
- return dao.loadOrders(id);
- }
- ……
(2)创建测试JSP页面index.jsp。
- <%@ page language='java' pageEncoding='gb2312'%>
- <%@ page import='com.bean.TestBean'%>
- <%@ page import='com.ORM.*'%>
- <%@ page import='java.util.*'%>
- <%@ page import='java.text.NumberFormat'%>
- <jsp:useBean id='test' class='com.bean.TestBean' />
- <html>
- <head><title>Hibernate的一对多双向关联关系映射</title></head>
- <body>
- <h2>Hibernate的一对多双向关联关系映射</h2><hr>
- <%
- test.addCustomer();
- Integer id = new Integer(1);
- Customer customer = test.loadCustomer(id);
- test.addOrders(customer);
- test.addOrders(customer);
- test.addOrders(customer);
- //根据指定的客户,得到该客户的所有订单
- NumberFormat nf = NumberFormat.getCurrencyInstance();
- out.println('<br>客户'+customer.getCname()+'的所有订单:');
- Iterator it = customer.getOrders().iterator();
- Orders order = null;
- while (it.hasNext()){
- order = (Orders)it.next();
- out.println('<br>订单号:'+order.getOrderno());
- out.println('<br>订单金额:'+nf.format(order.getMoney()));
- }
- //根据指定的订单,得到其所属的客户
- order = test.loadOrders(new Integer(1));
- customer = order.getCustomer();
- out.println('<br>');
- out.println('<br>订单号为'+order.getOrderno().trim()+'的所属客户为:'
- +customer.getCname());
- %>
- </body>
- </html>
index.jsp运行分析。
(1)执行了test.addCustomer()以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】insert into customer (CNAME, BANK, PHONE) values
- ('张三', '123456789123456789', '020-12345678')
(2)执行了test.loadCustomer(id)以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】select * from customer where ID=1
- select * from orders where CUSTOMER_ID=1
由于Customer.hbm.xml中的lazy='false',在装载Customer后,会立即装载与当前Customer对象一对多关联的所有Orders对象。
(3)执行了test.addOrders(customer);以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】insert into orders(ORDERNO,MONEY,CUSTOMER_ID)
- values('1163858590843',7158.76,1)
(4)执行了test.loadOrders(new Integer(1));以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】select * from orders where ID=1
- select * from customer where ID=1
由于Orders.hbm.xml中的lazy='false',在装载Orders后,会立即装载与当前Orders对象多对一关联的Customer对象。
index.jsp运行效果如图4-20所示。
|
本实例的完整源代码请参考配套光盘的'源代码'部分。