Hibernate之关联关系(一对多)

发布时间:2026/7/28 17:54:54
Hibernate之关联关系(一对多) Hibernate关联关系一对多什么是关联(association)关联指的是类之间的引用关系。如果类A与类B关联那么被引用的类B将被定义为类A的属性。例如:t_hibernate_ordert_hibernate_order_item一个订单对应多个订单项class Order{ private ListOrderItem orderItems; } class OrderItem{ private Order order; } class B{ private String name; } public class A{ private B b new B; public A(){} }测试代码如下DemoDao.javapackage com.LHJ.three.dao; import java.util.List; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test; import com.LHJ.three.entity.Order; import com.LHJ.three.entity.OrderItem; import com.LHJ.two.util.SessionFactoryUtils; public class DemoDao { /** * 为了测试关系型映射文件配置准确 * 讲解insertfalseupdatefalse的用途 * param order * return */ public Integer addOrder(Order order) { Session session SessionFactoryUtils.openSession(); Transaction transaction session.beginTransaction(); Integer oid (Integer)session.save(order); transaction.commit(); session.close(); return oid; } public Integer addOrderItem(OrderItem orderItem) { Session session SessionFactoryUtils.openSession(); Transaction transaction session.beginTransaction(); Integer otid (Integer)session.save(orderItem); transaction.commit(); session.close(); return otid; } /** * 为了讲解懒加载的问题hibernate3.0后所有查询方式默认采用的是懒加载方式 * 1、查单个时存在问题代理对象已经关闭 * 2、查多个存在问题有性能的问题 * param order * return */ public Order getOrder(Order order) { Session session SessionFactoryUtils.openSession(); Transaction transaction session.beginTransaction(); Order o session.get(Order.class, order.getOrderId()); if(o ! null new Integer(1).equals(order.getInitChildren())) { Hibernate.initialize(o.getOrderItems()); // System.out.println(o.getOrderItems()); } transaction.commit(); session.close(); return o; } public ListOrder getOrderList() { Session session SessionFactoryUtils.openSession(); Transaction transaction session.beginTransaction(); ListOrder list session.createQuery(from Order).list(); transaction.commit(); session.close(); return list; } /** * z主表的数据不能随便删除得先删除从表中对应信息才能删除主表的信息。 * param order */ public void delOrder(Order order) { Session session SessionFactoryUtils.openSession(); Transaction transaction session.beginTransaction(); Order order2 session.get(Order.class, order.getOrderId()); for (OrderItem oi : order2.getOrderItems()) { session.delete(oi); } session.delete(order2); // session.delete(order); transaction.commit(); session.close(); } }DemoDaoTest.javapackage com.LHJ.three.dao; import static org.junit.Assert.*; import java.util.List; import org.junit.Test; import com.LHJ.three.entity.Order; import com.LHJ.three.entity.OrderItem; public class DemoDaoTest { private DemoDao demoDao new DemoDao(); Test public void testAddOrder() { Order order new Order(); order.setOrderNo(LHJ); for (int i 0; i 6; i) { OrderItem oi new OrderItem(); oi.setProductId(10i); oi.setQuantity(20i); // demoDao.addOrderItem(oi); order.getOrderItems().add(oi); oi.setOrder(order); } demoDao.addOrder(order); } Test public void testAddOrderItem() { OrderItem oi new OrderItem(); oi.setProductId(66); oi.setQuantity(66); Order order new Order(); order.setOrderId(11); oi.setOrder(order); demoDao.addOrderItem(oi); } Test public void testGetOrder() { Order order new Order(); order.setOrderId(11); order.setInitChildren(1); Order o demoDao.getOrder(order); //failed to lazily initialize a collection of role: //com.LHJ.three.entity.Order.orderItems, could not initialize proxy - no Session System.out.println(o.getOrderNo()); System.out.println(o.getOrderItems().size()); } Test public void testGetOrderList() { ListOrder orderList demoDao.getOrderList(); for (Order order: orderList) { System.out.println(order.getOrderNo()); // System.out.println(order.getOrderItems().size()); } } Test public void testDelOrder() { Order order new Order(); order.setOrderId(11); this.demoDao.delOrder(order); } }然后两个实体类Order.javapackage com.LHJ.three.entity; import java.util.ArrayList; import java.util.List; public class Order { private Integer orderId; private String orderNo; private ListOrderItem orderItems new ArrayListOrderItem(); private Integer initChildren 0;//0代表默认懒加载1代表强制加载 public Integer getInitChildren() { return initChildren; } public void setInitChildren(Integer initChildren) { this.initChildren initChildren; } public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId orderId; } public String getOrderNo() { return orderNo; } public void setOrderNo(String orderNo) { this.orderNo orderNo; } public ListOrderItem getOrderItems() { return orderItems; } public void setOrderItems(ListOrderItem orderItems) { this.orderItems orderItems; } Override public String toString() { return Order [orderId orderId , orderNo orderNo , orderItems orderItems ]; } }OrderItem.javapackage com.LHJ.three.entity; public class OrderItem { private Integer orderItemId; private Integer productId; private Integer quantity; private Integer oid; private Order order; public Integer getOrderItemId() { return orderItemId; } public void setOrderItemId(Integer orderItemId) { this.orderItemId orderItemId; } public Integer getProductId() { return productId; } public void setProductId(Integer productId) { this.productId productId; } public Integer getQuantity() { return quantity; } public void setQuantity(Integer quantity) { this.quantity quantity; } public Integer getOid() { return oid; } public void setOid(Integer oid) { this.oid oid; } public Order getOrder() { return order; } public void setOrder(Order order) { this.order order; } Override public String toString() { return OrderItem [orderItemId orderItemId , productId productId , quantity quantity , oid oid , order order ]; } }然后对应的两个映射文件Order.hbm.xml?xml version1.0 encodingUTF-8? !DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd hibernate-mapping class namecom.LHJ.three.entity.Order tablet_hibernate_order id nameorderId typejava.lang.Integer columnorder_id generator classincrement / /id property nameorderNo typejava.lang.String columnorder_no /property !-- bag标签: name:当前要映射的类的关联属性 cascade:维护关联关系 inverse:决定由谁来维护关联关系 key标签: column:表的外键对应的列段 one-to-many: class:关联属性对应的类的全路径名 -- bag nameorderItems cascadesave-update inversetrue key columnoid/key one-to-many classcom.LHJ.three.entity.OrderItem/ /bag /class /hibernate-mappingOrderItem.hbm.xml?xml version1.0 encodingUTF-8? !DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd hibernate-mapping class namecom.LHJ.three.entity.OrderItem tablet_hibernate_order_item id nameorderItemId typejava.lang.Integer columnorder_item_id generator classincrement / /id property nameproductId typejava.lang.Integer columnproduct_id /property property namequantity typejava.lang.Integer columnquantity /property property nameoid typejava.lang.Integer columnoid insertfalse updatefalse /property !-- many-to-one:多对一的配置(因为多个订单项对应一个订单) name:指的是当前所要映射的类com.LHJ.three.entity.OrderItem的关联属性order class:指的是关联属性的类别(全路径名) column:这里填的是外键 -- many-to-one nameorder classcom.LHJ.three.entity.Order columnoid/many-to-one /class /hibernate-mapping然后在主配置文件hibernate.cfg.xml中配置因为在OrderItem.hbm.xml中有两个对oid进行了维护 所以我们需要放弃一个然后解决加入箭头所指的代码就行了。增加测试结果增加订单项结果懒加载会出现错误有两种解决方案第一种在bag标签里面添加箭头所指代码就行了结果这样子虽然能处理问题 但是对性能影响很不好 因为它有多少条数据 sql语句就会执行多少条1。 所以不推荐使用第二种在order实体类中写一个属性 并给它提供set get方法更改dao方法然后在测试方法中加入这行代码结果测试删除结果