欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

hibernate的一对多双向关联映射----客户和订单关系

发布时间:2025/3/20 编程问答 40 豆豆
生活随笔 收集整理的这篇文章主要介绍了 hibernate的一对多双向关联映射----客户和订单关系 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

客户和订单关系:客户是一的一方,订单是多的一方。

customer表:


CREATE TABLE `customer` ( `ID` int(4) NOT NULL AUTO_INCREMENT , `CNAME` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `BANK` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `PHONE` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , PRIMARY KEY (`ID`) )orders表:


CUSTOMER_ID是外键!


CREATE TABLE `orders` ( `ID` int(4) NOT NULL AUTO_INCREMENT , `ORDERNO` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `MONEY` double(10,2) NULL DEFAULT NULL , `CUSTOMER_ID` int(4) NULL DEFAULT NULL , PRIMARY KEY (`ID`), FOREIGN KEY (`CUSTOMER_ID`) REFERENCES `customer` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE, INDEX `CUSTOMER_ID` (`CUSTOMER_ID`) USING BTREE )PO对象

Customer.java

package com.PO;import java.util.HashSet; import java.util.Set;/*** Company entity. @author tuke*/public class Customer implements java.io.Serializable { private Integer id; private String cname; //客户名称private String bank; //银行账号private String phone; //电话号码private Set<Orders> orderses = new HashSet<Orders>(); //关联另外一个类// Constructors/** default constructor */public Customer() {}/** full constructor */public Customer(String cname, String bank, String phone, Set<Orders> orderses) {this.cname = cname;this.bank = bank;this.phone = phone;this.orderses = orderses;}// Property accessorspublic Integer getId() {return this.id;} public void setId(Integer id) {this.id = id;}public String getCname() {return this.cname;} public void setCname(String cname) {this.cname = cname;}public String getBank() {return this.bank;}public void setBank(String bank) {this.bank = bank;}public String getPhone() {return this.phone;}public void setPhone(String phone) {this.phone = phone;}public Set<Orders> getOrderses() {return this.orderses;}public void setOrderses(Set<Orders> orderses) {this.orderses = orderses;}}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><class name="com.PO.Customer" table="customer" catalog="onetomany"><id name="id" type="integer"><column name="ID" /><generator class="identity"></generator></id><property name="cname" column="CNAME" type="string"></property><property name="bank" column="BANK" type="string"> </property> <property name="phone" column="PHONE" type="string"> </property><!-- 一对多双向映射customer到orders,单的一方配置 ,name是PO类Company的属性,table是关联表名,如果设置成inverse为true,以设定一方到多方的设定是逆向映射,即可以从多放引导到一方。一定要加lazy="false"否则会出现延迟加载错误--><set name="orderses" table="orders" inverse="true" lazy="false" cascade="all" ><key column="CUSTOMER_ID"/><!--外键字段: <key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致 --><one-to-many class="com.PO.Orders" /><!-- 用关联表对应的PO类实例做value值 --></set></class> </hibernate-mapping> Orders.java

package com.PO;/*** Orders entity. @author tuke*/public class Orders implements java.io.Serializable {private Integer id; private String orderno;private double money;private Customer customer;//关联customer/** default constructor */public Orders() {}/** full constructor */public Orders(Customer customer, String orderno, double money) {this.customer = customer;this.orderno = orderno;this.money = money;}// Property accessorspublic Integer getId() {return this.id;}public void setId(Integer id) {this.id = id;}public Customer getCompany() {return this.customer;}public void setCompany(Customer customer) {this.customer = customer;}public String getOrderno() {return this.orderno;}public void setOrderno(String orderno) {this.orderno = orderno;}public double getMoney() {return this.money;}public void setMoney(double money) {this.money = money;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}}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="com.PO.Orders" table="orders" catalog="onetomany"><id name="id" type="integer"><column name="ID" /><generator class="identity"></generator></id><property name="orderno" column="ORDERNO" type="string"> </property><property name="money" column="MONEY" type="double"> </property><!-- 一对多双向关联映射中,多的一方配置manytoone ,name是PO属性,一定要加lazy="false"否则会出现延迟加载错误--><many-to-one name="customer" column="CUSTOMER_ID" class="com.PO.Customer" lazy="false"></many-to-one></class> </hibernate-mapping> TestBean.java

package com.test;import java.util.Random;import com.PO.Customer; import com.PO.Orders; import com.dao.OneManyDao;public class TestBean {OneManyDao dao=new OneManyDao();Random rnd=new Random();public void addCustomer(){Customer customer=new Customer();customer.setCname("tuke");customer.setBank("中国银行");customer.setPhone("027-12121221");//数据库操作dao.addCustomer(customer);}public Customer loadCustomer(Integer id){return dao.loadCustomer(id);}//为客户customer添加订单orders,被控方操作public void addOrders(Customer customer){//随机生成order对象Orders order=new Orders();order.setOrderno(new Integer(rnd.nextInt()*10000).toString());order.setMoney(new Double(rnd.nextDouble()*10000));order.setCustomer(customer);//如果映射文件正确,则orders表的CUSTOMER_ID字段会有customer的ID//把生成的order对象,加入customer的set集合中customer.getOrderses().add(order);System.out.println( customer.getOrderses().contains(order));dao.addOrders(order);}public Orders loadOrders(Integer id){return dao.loadOrders(id);} } OneManyDao.java

package com.dao;import org.hibernate.Session; import org.hibernate.Transaction;import SessionFactory.HibernateSessionFactory;import com.PO.Customer; import com.PO.Orders;/*** Data access object (DAO) for domain model* @author tuke*/ public class OneManyDao {//添加客户信息public void addCustomer(Customer customer){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();//保存customer对象的同时,会保存其包含的所有订单session.saveOrUpdate(customer);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("添加客户失败!");}finally{HibernateSessionFactory.closeSession();}}//加载客户信息public Customer loadCustomer(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Customer customer=null;try{ts=session.beginTransaction();//加载customer信息时,同样会加载其所有的订单信息customer=(Customer)session.get(Customer.class, id);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("获取客户失败!");}finally{HibernateSessionFactory.closeSession();}return customer;}//添加订单信息public void addOrders(Orders order){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();session.save(order);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("添加订单失败!");}finally{HibernateSessionFactory.closeSession();}}//加载订单信息public Orders loadOrders(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Orders order=null;try{ts=session.beginTransaction();order=(Orders)session.get(Orders.class, id);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("获取订单失败!");}finally{HibernateSessionFactory.closeSession();}return order;}}测试页面test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page import="com.PO.*" import="com.test.*" import="java.text.NumberFormat"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><title>hibernate的一对多双向关联关系映射</title><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body> <h2>hibernate的一对多双向关联关系映射</h2><hr><jsp:useBean id="test" class="com.test.TestBean"></jsp:useBean><%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<Orders> it=customer.getOrderses().iterator();Orders order=null;while(it.hasNext()){order=(Orders)it.next();System.out.println(order.getOrderno());out.println("<br>订单号:"+order.getOrderno());out.println("<br>订单金额:"+nf.format(order.getMoney()));}//根据指定的订单,得到其所属的客户order=test.loadOrders(new Integer(28));customer=order.getCustomer();out.println("<br>");out.println("<br>订单号为:"+order.getOrderno().trim()+"的所属客户为:"+customer.getCname());%></body> </html> 测试结果:






控制台打印的sql语句是:

Hibernate: insert intoonetomany.customer(CNAME, BANK, PHONE) values(?, ?, ?) Hibernate: selectcustomer0_.ID as ID1_0_,customer0_.CNAME as CNAME1_0_,customer0_.BANK as BANK1_0_,customer0_.PHONE as PHONE1_0_ fromonetomany.customer customer0_ wherecustomer0_.ID=? //上面是save和load一个customer Hibernate: selectorderses0_.CUSTOMER_ID as CUSTOMER4_1_,orderses0_.ID as ID1_,orderses0_.ID as ID0_0_,orderses0_.ORDERNO as ORDERNO0_0_,orderses0_.MONEY as MONEY0_0_,orderses0_.CUSTOMER_ID as CUSTOMER4_0_0_ fromonetomany.orders orderses0_ whereorderses0_.CUSTOMER_ID=? true Hibernate: insert intoonetomany.orders(ORDERNO, MONEY, CUSTOMER_ID) values(?, ?, ?) true Hibernate: insert intoonetomany.orders(ORDERNO, MONEY, CUSTOMER_ID) values(?, ?, ?) true Hibernate: insert intoonetomany.orders(ORDERNO, MONEY, CUSTOMER_ID) values(?, ?, ?) //上面是给客户添加三个订单的sql 741563392 -1674530192 -635127520 //这是三个customer实例中set集合里的三个订单号 Hibernate: selectorders0_.ID as ID0_0_,orders0_.ORDERNO as ORDERNO0_0_,orders0_.MONEY as MONEY0_0_,orders0_.CUSTOMER_ID as CUSTOMER4_0_0_ fromonetomany.orders orders0_ whereorders0_.ID=? Hibernate: selectcustomer0_.ID as ID1_0_,customer0_.CNAME as CNAME1_0_,customer0_.BANK as BANK1_0_,customer0_.PHONE as PHONE1_0_ fromonetomany.customer customer0_ wherecustomer0_.ID=? Hibernate: selectorderses0_.CUSTOMER_ID as CUSTOMER4_1_,orderses0_.ID as ID1_,orderses0_.ID as ID0_0_,orderses0_.ORDERNO as ORDERNO0_0_,orderses0_.MONEY as MONEY0_0_,orderses0_.CUSTOMER_ID as CUSTOMER4_0_0_ fromonetomany.orders orderses0_ whereorderses0_.CUSTOMER_ID=? 总结:

一对多双向关联映射:
* 在“一”一端的集合上使用<key>,<key>标签指定的是外键字段,在对方表中加入一个外键指向一一端
* 在多一端采用<many-to-one>

注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误

关键配置代码如下:

<!-- 一对多双向映射customer到orders,单的一方配置 ,name是PO类Company的属性,table是关联表名,如果设置成inverse为true,以设定一方到多方的设定是逆向映射,即可以从多放引导到一方。一定要加lazy="false"否则会出现延迟加载错误--><set name="orderses" table="orders" inverse="true" lazy="false" cascade="all" ><key column="CUSTOMER_ID"/><!--外键字段: <key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致 --><one-to-many class="com.PO.Orders" /><!-- 用关联表对应的PO类实例做value值 --></set> <!-- 一对多双向关联映射中,多的一方配置manytoone ,name是PO属性,一定要加lazy="false"否则会出现延迟加载错误--><many-to-one name="customer" column="CUSTOMER_ID" class="com.PO.Customer" lazy="false"></many-to-one>











总结

以上是生活随笔为你收集整理的hibernate的一对多双向关联映射----客户和订单关系的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。