4.3.8 映射多对多单向关联关系
在电子商务应用中,多对多的关联关系也非常普遍,诸如订单与商品、商品与购物车之间的关系均属于多对多的关联关系。多对多关联在关系数据库中不能直接实现,还必须依赖一张连接表用于保存这种关联关系。
下面以订单表(见表4-17)与商品表(见表4-18)为例来说明多对多单向关联关系的映射,订单表与商品表的连接表为selecteditems(见表4-19)。
表4-17 订单表orders
表4-18 商品表items
表4-19 连接表selecteditems
订单表与商品表之间的多对多单向关联通过连接表来实现,如图4-24所示。
持久化类订单到商品之间的多对多单向关联关系如图4-25所示。
持久化类Orders.java:
- package com.ORM;
- import java.io.Serializable;
- import java.util.*;
- public class Orders implements Serializable{
- private java.lang.Integer id; //ID号
- private java.lang.String orderno; //订单编号
- private java.lang.Double money; //订单金额
- private Set items = new HashSet(); //商品集合
- public Orders(){}
- //省略上述各属性的get/set方法对
- }
持久化类Items.java:
- package com.ORM;
- import java.io.Serializable;
- public class Items implements Serializable{
- private java.lang.Integer id; //ID号
- private java.lang.String itemno; //商品编号
- private java.lang.String itemname; //商品名称
- public Items(){}
- //省略上述各属性的get/set方法对
- }
items表与Items 类的ORM映射文件Items.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="Items" table="items">
- <id name="id" column="ID" type="integer">
- <generator class="identity"/>
- </id>
- <property name="itemno" column="ITEMNO" type="string" />
- <property name="itemname" column="ITEMNAME" type="string" />
- </class>
- </hibernate-mapping>
orders表与Orders类的 ORM映射文件Orders.hbm.xml:
(1)创建供测试用的TestBean.java。
- ……
- //新增一个商品
- public void addItem(String itemno,String itemname){
- Items item = new Items();
- item.setItemno(itemno);
- item.setItemname(itemname);
- dao.addItems(item);
- }
- //新增一个订单
- public void addOrder(String orderno,Double money,Set items){
- Orders order = new Orders();
- order.setOrderno(orderno);
- order.setMoney(money);
- order.setItems(items); //设置Orders到Items的多对多单向关联
- dao.addOrders(order);
- }
- //装载一个商品
- public Items loadItems(Integer id){
- return dao.loadItems(id);
- }
- //装载一个订单
- 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.*"%>
- <jsp:useBean id="test" class="com.bean.TestBean" />
- <html>
- <head><title>Hibernate的多对多单向关联关系映射</title> </head>
- <body>
- <h2>Hibernate的多对多单向关联关系映射</h2><hr>
- <%
- //新增3个商品
- test.addItem("001","A商品");
- test.addItem("002","B商品");
- test.addItem("003","C商品");
- //选购其中的两个商品
- Set items = new HashSet();
- items.add(test.loadItems(new Integer(2)));
- items.add(test.loadItems(new Integer(3)));
- //将选购的商品产生一张订单
- test.addOrder("A00001",new Double(2100.5),items);
- //装载订单
- Orders order = test.loadOrders(new Integer(1));
- out.println("<br>订单""+order.getOrderno().trim()+""中的商品清单为:");
- Iterator it = order.getItems().iterator();
- Items item = null;
- while (it.hasNext()){
- item = (Items)it.next();
- out.println("<br>商品编号:"+item.getItemno().trim());
- out.println("<br>商品名称:"+item.getItemname().trim());
- }
- %>
- </body>
- </html>
index.jsp运行分析。
(1)执行了"新增3个商品"以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】insert into items(ITEMNO,ITEMNAME) values("001","A商品")
- insert into items(ITEMNO,ITEMNAME) values("002","B商品")
- insert into items(ITEMNO,ITEMNAME) values("003","C商品")
(2)执行了"选购其中的两个商品"以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】select * from items where ID=2
- select * from items where ID=3
(3)执行了"将选购的商品产生一张订单"以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】insert into orders(ORDERNO,MONEY) values("A00001",2100.5)
- insert into selecteditems(ORDERID,ITEMID) values (1,2)
- insert into selecteditems(ORDERID,ITEMID) values (1,3)
(4)执行了"装载订单"以后,Hibernate向数据库服务器提交的SQL语句为:
- 【SQL】select * from orders where ID=1
- select a.*,b.* from selecteditems a inner join items b on a.ITEMID=b.ID
- where a.ORDERID=1
index.jsp运行效果如图4-26所示。
本实例的完整源代码请参考配套光盘的"源代码"部分。