投射一对多双向关联关系

映射一对多双向关联关系

本文转自:http://mba.shengwushibie.com/itbook/BookChapter.asp?id=4341

 

 

4.3.6 映射一对多双向关联关系

 

4.3.6  映射一对多双向关联关系

在电子商务应用中,经常会有这样的需求:根据给定的客户,得到该客户的所有订单;根据给定的订单,得到该订单的所属客户。对于这种双向关联的情况,在Hibernate应用中,也有人叫多对一双向关联,只是叫法不同而已,都是通过映射一对多双向关联关系来实现的。

不管是多对一单向关联还是(一对多)多对一双向关联,在关系型数据库中的表现方式都是一样的,均通过外键参照来实现如图4-18所示。

投射一对多双向关联关系 

只是在持久化类与ORM映射文件中单向关联与双向关联存在一些区别而已,如图4-19所示。

 

投射一对多双向关联关系  

 

持久化类Customer.java:

  1. package com.ORM;  
  2. import java.io.Serializable;  
  3. import java.util.*;  
  4. public class Customer implements Serializable{  
  5.     private java.lang.Integer id;               //ID号  
  6.     private java.lang.String cname;                 //客户姓名  
  7.     private java.lang.String bank;              //银行账号  
  8.     private java.lang.String phone;                 //联系电话  
  9.     private Set orders = new HashSet();             //订单集合  
  10.     public Customer(){}      
  11.     //省略上述各属性的get/set方法对  

持久化类Orders.java:

  1. package com.ORM;  
  2. import java.io.Serializable;  
  3. public class Orders implements Serializable{  
  4.     private java.lang.Integer id;               //ID号  
  5.     private java.lang.String orderno;               //订单编号  
  6.     private java.lang.Double money;                 //订单金额  
  7.     private Customer customer;              //订单的所属客户  
  8.     public Orders(){}  
  9.     //省略上述各属性的get/set方法对  

customer表与Customer类的ORM映射文件Customer.hbm.xml:

  1. <?xml version='1.0' encoding='UTF-8'?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3. '-//Hibernate/Hibernate Mapping DTD 3.0//EN' 
  4. 'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd' >  
  5. <hibernate-mapping package='com.ORM'>  
  6.     <class name='Customer' table='customer'>  
  7.         <id name='id' column='ID' type='integer'>  
  8.             <generator class='identity'/>  
  9.         </id>   
  10.         <property name='cname' column='CNAME' type='string' />  
  11.         <property name='bank' column='BANK' type='string' /> 

 

投射一对多双向关联关系  

 

orders表与Orders类的ORM映射文件Orders.hbm.xml:

 

投射一对多双向关联关系  

 

(1)创建供测试用的TestBean.java。

  1. ……  
  2.     public void addCustomer(){  
  3. Customer customer = new Customer();  
  4. customer.setCname('张三');  
  5. customer.setBank('123456789123456789');  
  6. customer.setPhone('020-12345678');  
  7. dao.addCustomer(customer);  
  8.     }     
  9.     public Customer loadCustomer(Integer id){  
  10. return dao.loadCustomer(id);  
  11.     }  
  12.     public void addOrders(Customer customer){  
  13. Orders order = new Orders();  
  14. order.setOrderno(new Long(System.currentTimeMillis()).toString());  
  15. order.setMoney(new Double(rnd.nextDouble()*10000));  
  16. //将Customer与Orders实例进行双向关联  
  17. order.setCustomer(customer);  
  18. customer.getOrders().add(order);  
  19. dao.addOrders(order);  
  20.     }     
  21.     public Orders loadOrders(Integer id){  
  22. return dao.loadOrders(id);  
  23.     }  
  24. …… 

(2)创建测试JSP页面index.jsp。

  1. <%@ page language='java' pageEncoding='gb2312'%>  
  2. <%@ page import='com.bean.TestBean'%>  
  3. <%@ page import='com.ORM.*'%>  
  4. <%@ page import='java.util.*'%>  
  5. <%@ page import='java.text.NumberFormat'%>  
  6. <jsp:useBean id='test' class='com.bean.TestBean' />  
  7. <html>  
  8.   <head><title>Hibernate的一对多双向关联关系映射</title></head>    
  9.   <body>  
  10.     <h2>Hibernate的一对多双向关联关系映射</h2><hr>  
  11.     <%  
  12. test.addCustomer();  
  13. Integer id = new Integer(1);  
  14. Customer customer = test.loadCustomer(id);  
  15. test.addOrders(customer);  
  16. test.addOrders(customer);  
  17. test.addOrders(customer);  
  18. //根据指定的客户,得到该客户的所有订单      
  19. NumberFormat nf = NumberFormat.getCurrencyInstance();  
  20. out.println('<br>客户'+customer.getCname()+'的所有订单:');  
  21. Iterator it = customer.getOrders().iterator();  
  22. Orders order = null;  
  23. while (it.hasNext()){  
  24.     order = (Orders)it.next();  
  25.     out.println('<br>订单号:'+order.getOrderno());  
  26.     out.println('<br>订单金额:'+nf.format(order.getMoney()));     
  27. }  
  28. //根据指定的订单,得到其所属的客户  
  29. order = test.loadOrders(new Integer(1));  
  30. customer = order.getCustomer();  
  31. out.println('<br>');  
  32. out.println('<br>订单号为'+order.getOrderno().trim()+'的所属客户为:' 
  33. +customer.getCname());  
  34.     %>  
  35.   </body>  
  36. </html> 

index.jsp运行分析。

(1)执行了test.addCustomer()以后,Hibernate向数据库服务器提交的SQL语句为:

  1. 【SQL】insert into customer (CNAME, BANK, PHONE) values 
  2. ('张三''123456789123456789', '020-12345678'

(2)执行了test.loadCustomer(id)以后,Hibernate向数据库服务器提交的SQL语句为:

  1. 【SQL】select * from customer where ID=1 
  2. select * from orders where CUSTOMER_ID=1 

由于Customer.hbm.xml中的lazy='false',在装载Customer后,会立即装载与当前Customer对象一对多关联的所有Orders对象。

(3)执行了test.addOrders(customer);以后,Hibernate向数据库服务器提交的SQL语句为:

  1. 【SQL】insert into orders(ORDERNO,MONEY,CUSTOMER_ID) 
  2. values('1163858590843',7158.76,1

(4)执行了test.loadOrders(new Integer(1));以后,Hibernate向数据库服务器提交的SQL语句为:

  1. 【SQL】select * from orders where ID=1 
  2. select * from customer where ID=1 

由于Orders.hbm.xml中的lazy='false',在装载Orders后,会立即装载与当前Orders对象多对一关联的Customer对象。

index.jsp运行效果如图4-20所示。

 

投射一对多双向关联关系  

 

本实例的完整源代码请参考配套光盘的'源代码'部分。