hibernate之关联关系(一对多)

什么是关联(association)?


 关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:
class B{
private String name;
}
public class A{
private B b = new B;
public A(){}
}

关联的分类:关联可以分为一对一、一对多/多对一、多对多关联

关联是有方向的

Hibrnate一对多实现

数据库t_hibernate_order_item

t_hibernate_order

实现类和实现类配置

订单实体类
 1 public class Order {
 2     private Integer orderId;
 3     private String orderNo;
 4     //建立了关联关系 一个订单对应着多个订单
 5     private List<OrderItem> orderItems=new ArrayList<>();
 6     private Integer initChildren =0;//0是懒加载 1:false
11     
12     
13     public Integer getInitChildren() {
14         return initChildren;
15     }
16     public void setInitChildren(Integer initChildren) {
17         this.initChildren = initChildren;
18     }
19     public List<OrderItem> getOrderItems() {
20         return orderItems;
21     }
22     public void setOrderItems(List<OrderItem> orderItems) {
23         this.orderItems = orderItems;
24     }
25     public Integer getOrderId() {
26         return orderId;
27     }
28     public void setOrderId(Integer orderId) {
29         this.orderId = orderId;
30     }
31     public String getOrderNo() {
32         return orderNo;
33     }
34     public void setOrderNo(String orderNo) {
35         this.orderNo = orderNo;
36     }
37     @Override
38     public String toString() {
39         return "Order [orderId=" + orderId + ", orderNo=" + orderNo + "]";
40     }
41     
42 
43 }
订单实体类配置
 1 <hibernate-mapping>
 2   
 3     <class name="three.entity.Order" table="t_hibernate_order">
 4         <id name="orderId" type="java.lang.Integer" column="order_id">
 5             <generator class="increment" />
 6         </id>
 7         <property name="orderNo" type="java.lang.String" column="order_no">
 8         </property>
 9         <!-- 
10              bag标签:是否横加载,默认是懒加载的 true    懒汉模式
11              name:类的关联属性名
12              cascade: 级联关系  级联新增与修改
13              inverse: 关联关系交给对方控制默认true,当前类不维护关联关系
14              
15              
16              子标签key:
17              colunn:主表的主键:从表的外键
18              子标签one—to-many:
19              class:外检对应的实体类             
20          -->
21         <bag lazy="false" name="orderItems" cascade="save-update" inverse="true" >
22            <key column="oid"></key>
23            <one-to-many class="three.entity.OrderItem"/>
24         </bag>
25         
26     </class>
27 
28 </hibernate-mapping>

订单项实体类

 1 public class OrderItem {
 2     private Integer orderItemId;
 3     private Integer productId;
 4     private Integer quantity;
 5     private Integer oid;
 6     //建立关联关系   一个订单对应的是一个订单
 7     private Order order;
 8     
 9     
10     public Order getOrder() {
11         return order;
12     }
13     public void setOrder(Order order) {
14         this.order = order;
15     }
16     public Integer getOrderItemId() {
17         return orderItemId;
18     }
19     public void setOrderItemId(Integer orderItemId) {
20         this.orderItemId = orderItemId;
21     }
22     public Integer getProductId() {
23         return productId;
24     }
25     public void setProductId(Integer productId) {
26         this.productId = productId;
27     }
28     public Integer getQuantity() {
29         return quantity;
30     }
31     public void setQuantity(Integer quantity) {
32         this.quantity = quantity;
33     }
34     public Integer getOid() {
35         return oid;
36     }
37     public void setOid(Integer oid) {
38         this.oid = oid;
39     }
40     @Override
41     public String toString() {
42         return "OrderItem [orderItemId=" + orderItemId + ", productId=" + productId + ", quantity=" + quantity
43                 + ", oid=" + oid + "]";
44     }
45     
46 
47 }

订单项配置

 1 <hibernate-mapping>
 2     <class name="three.entity.OrderItem" table="t_hibernate_order_item">
 3         <id name="orderItemId" type="java.lang.Integer" column="order_item_id">
 4             <generator class="increment" />
 5         </id>
 6         <property name="productId" type="java.lang.Integer" column="product_id">
 7         </property>
 8         <property name="quantity" type="java.lang.Integer" column="quantity">
 9         </property>
10         <property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false">
11         </property>
12         <many-to-one name="order" class="three.entity.Order" column="oid"></many-to-one>
13     </class>
14 </hibernate-mapping>

dao方法

 1 public class DemoDao {
 2     /**
 3      * 为了测试关系型映射文件配置准确
 4      *     讲解insert=false,update=false的用途
 5      * @param order
 6      * @return
 7      */
 8     public Integer addOrder(Order order) {
 9         Session session = SessionFactoryUtils.openSession();
10         Transaction transaction = session.beginTransaction();
11         Integer oid = (Integer)session.save(order);
12         transaction.commit();
13         session.close();
14         return oid;
15     }
16     
17     public Integer addOrderItem(OrderItem orderItem) {
18         Session session = SessionFactoryUtils.openSession();
19         Transaction transaction = session.beginTransaction();
20         Integer otid = (Integer)session.save(orderItem);
21         transaction.commit();
22         session.close();
23         return otid;
24     }
25     
26     
27     
28     /**
29      * 为了讲解懒加载的问题(hibernate3.0后所有查询方式默认采用的是懒加载方式)
30      *     1、查单个时存在问题,代理对象已经关闭
31      *     2、查多个存在问题,有性能的问题
32      * @param order
33      * @return
34      */
35     public Order getOrder(Order order) {
36         Session session = SessionFactoryUtils.openSession();
37         Transaction transaction = session.beginTransaction();
38         Order o = session.get(Order.class, order.getOrderId());
39         if(o != null && new Integer(1).equals(order.getInitChildren())) {
40             //强制加载关联对象
41             Hibernate.initialize(o.getOrderItems());
42 //            System.out.println(o.getOrderItems());
43         }
44         transaction.commit();
45         session.close();
46         return o;
47     }
48     
49     public List<Order> getOrderList() {
50         Session session = SessionFactoryUtils.openSession();
51         Transaction transaction = session.beginTransaction();
52         List<Order> list = session.createQuery("from Order").list();
53         transaction.commit();
54         session.close();
55         return list;
56     }
57     
58     /**
59      * z主表的数据不能随便删除,得先删除从表中对应信息,才能删除主表的信息。
60      * @param order
61      */
62     public void delOrder(Order order) {
63         Session session = SessionFactoryUtils.openSession();
64         Transaction transaction = session.beginTransaction();
65         Order order2 = session.get(Order.class, order.getOrderId());
66         for (OrderItem oi : order2.getOrderItems()) {
67             session.delete(oi);
68         }
69         session.delete(order2);
70 //        session.delete(order);
71         transaction.commit();
72         session.close();
73     }
74 
75 }

DemoDaoTest junit测试类

public class DemoDaoTest {
    
    private DemoDao demoDao =new DemoDao();
    

//    @Before
//    public void setUp() throws Exception {
//        System.out.println("加载资源的");
//    }
//
//    @After
//    public void tearDown() throws Exception {
//        System.out.println("释放资源的");
//    }

    @Test
    public void testAddOrder() {
        Order order=new Order();
        order.setOrderNo("P20");
        OrderItem orderItem=null;
        for(int i=0;i<6;i++) {
            orderItem =new OrderItem();
            orderItem.setProductId(10+i);
            orderItem.setQuantity(20+i);
            //维护关联关系
            orderItem.setOrder(order);
            order.getOrderItems().add(orderItem);
        }
        demoDao.addOrder(order);
    }

    @Test
    public void testAddOrderItem() {
        OrderItem orderItem=null;
        for(int i=0;i<6;i++) {
            orderItem =new OrderItem();
            orderItem.setProductId(10+i);
            orderItem.setQuantity(20+i);
            //维护关联关系
            Order order=new Order();
            order.setOrderId(3);
            order.getOrderItems().add(orderItem);
            orderItem.setOrder(order);
            demoDao.addOrderItem(orderItem);
            
        }
    }

    @Test
    public void testGetOrder() {
        Order order=new Order();
        order.setOrderId(4);
        order.setInitChildren(1);
        Order o=this.demoDao.getOrder(order);
        //failed to lazily initialize a collection of role:
        //three.entity.Order.orderItems,
        //could not initialize proxy - no Session
        //原因, 操作了两次数据库,当lazy=false的时候,会让hibernate执行完两次操作,session才会关闭
        //当lazy=true 的时候,会让hibernate执行完一次操作,session就会关闭
        //从上面看lazy=false更好  但是为什么hibernate默认让他等于true
        //出于性能的考虑  所以hibernate3.0出现lazy这个属性,并让他默认等于true,也就是说不加载关联属性
        List<OrderItem> orderItems=o.getOrderItems();
        for(OrderItem orderItem : orderItems) {
            System.out.println(orderItem);
        }
        System.out.println(o);
    }

    @Test
    public void testGetOrderList() {
        List<Order> orderList=this.demoDao.getOrderList();
        for(Order order : orderList) {
            for(OrderItem orderItem : order.getOrderItems()) {
                System.out.println(orderItem);
            }
            System.out.println(order);
        }    }

    @Test
    public void testDelOrder() {
        Order order=new Order();
        order.setOrderId(4);
        this.demoDao.delOrder(order);
    }

}

以上有详细的代码,大家可以去测试测试

hibernate框架一对多 的执行原理:
 1 hibernate框架一对多 的执行原理:
 2 
 3       1、对hibernate. cfg. xml进行建模,等到sessionfactory对象2、并且拿到mapping resource里 的内容3、拿到了Order . hbm . xm1配置文佳
 4 
 5       4、可以再次建模,拿到了three . entity. Order,以及t_ hibernate_ order
 6 
 7       类属性、以及表列段
 8 
 9       5、生成动态的sql. select  orderId, orderNo from t_hibernate_order;
10 
11       孰行sql最終得到meterDat a源数据模型
12 
13       orderId, orderNo
14       1  P15  
15       5  P67  
16       7  P78  
17       8  P1019 
18       9  P20
19 
20       6、Order o1 = Class. forName( "three . entity . Order") . newInstance(0):
21 
22       o1. setOrderId(1);
23       o1. setOrderNo(p1)
24 
25              最終得到:
26       List<Order> list = new ArrayList();1ist.add(o1);
27             最終1ist中的所有order突例都有値了; (这里只是出来里面的非外键列段,原理完全跟basedao一样)
28       7.处理关联关系:orderIems 哦i的three.entity.OrderItem 
29         
30                 通过one-to-many这个标签以及class对应的全路径名会找对   应的全路径名队员的专属类
31                 也就是找到了Order.item.xml这个文件,拿到了他之后就可以拿到table t_hibernate_order_item
32       8.select * from t_hibernate_order_item;
33       
34                 最终得到了一个list<OrderItem> orderItems
35       9.给order的关联关系属性赋值
36             List<Order> List=new  ArrayList();
37                  for(Order o : list){
38                 o.setOrderItems(orderItems);
39                 }
原文地址:https://www.cnblogs.com/AluoKa/p/11191455.html