zoukankan      html  css  js  c++  java
  • Hibernate 关联关系(一对多)

    Hibernate 关联关系(一对多)

    1. 什么是关联(association)

    1.1 关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:
    class B{

    private String name;

    private List<A> bs = new arraylist();
        }

    public class A{
    private B b = new B;
    public A(){

          }
    }
    hibernate:orm框架、以面向对象的思想操作数据库

    1.2 关联的分类:关联可以分为一对一、一对多/多对一、多对多关联
    关联是有方向的

    案列:

    导入映射文件Order.hbm.xml和OrderItem.hbm.xml

    Order.hbm.xm

    进行关联关系的维护一对多的关系

    OrderItem.hbm.xml

    进行关联关系的维护 一对多的关系

    hibernate.cfg.xml(核心配置文件)添加映射文件OrderItem.hbm.xml和Order.hbm.xm

     对应映射文件的实体类

    Order.hbm.xml

    Order 
     1 package com.MavenHibernate.three.entity;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 public class Order {
     7 
     8     private Integer orderId;
     9     private String orderNo;
    10     private List<OrderItem> orderItems = new ArrayList<>();
    11     
    12     public List<OrderItem> getOrderItems() {
    13         return orderItems;
    14     }
    15 
    16     public void setOrderItems(List<OrderItem> orderItems) {
    17         this.orderItems = orderItems;
    18     }
    19 
    20     public List<OrderItem> getOrderItem() {
    21         return orderItems;
    22     }
    23     
    24     public void setOrderItem(List<OrderItem> orderItem) {
    25         this.orderItems = orderItem;
    26     }
    27     @Override
    28     public String toString() {
    29         return "Order [orderId=" + orderId + ", orderNo=" + orderNo + ", orderItem=" + orderItems + "]";
    30     }
    31     public Integer getOrderId() {
    32         return orderId;
    33     }
    34     public void setOrderId(Integer orderId) {
    35         this.orderId = orderId;
    36     }
    37     public String getOrderNo() {
    38         return orderNo;
    39     }
    40     public void setOrderNo(String orderNo) {
    41         this.orderNo = orderNo;
    42     }
    43     public Order(Integer orderId, String orderNo) {
    44         super();
    45         this.orderId = orderId;
    46         this.orderNo = orderNo;
    47     }
    48     public Order() {
    49         super();
    50     }
    51     
    52 }

    OrderItem.hbm.xml

    OrderItem

     1 package com.MavenHibernate.three.entity;
     2 
     3 public class OrderItem {
     4 
     5     private Integer orderItemId; 
     6     private Integer productId;
     7     private Integer quantity;
     8     private Integer oid;
     9     private Order order;
    10     
    11     public Order getOrder() {
    12         return order;
    13     }
    14     public void setOrder(Order order) {
    15         this.order = order;
    16     }
    17     @Override
    18     public String toString() {
    19         return "OrderItem [orderItemId=" + orderItemId + ", productId=" + productId + ", quantity=" + quantity
    20                 + ", oid=" + oid + ", order=" + order + "]";
    21     }
    22     public Integer getOrderItemId() {
    23         return orderItemId;
    24     }
    25     public void setOrderItemId(Integer orderItemId) {
    26         this.orderItemId = orderItemId;
    27     }
    28     public Integer getProductId() {
    29         return productId;
    30     }
    31     public void setProductId(Integer productId) {
    32         this.productId = productId;
    33     }
    34     public Integer getQuantity() {
    35         return quantity;
    36     }
    37     public void setQuantity(Integer quantity) {
    38         this.quantity = quantity;
    39     }
    40     public Integer getOid() {
    41         return oid;
    42     }
    43     public void setOid(Integer oid) {
    44         this.oid = oid;
    45     }
    46     public OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) {
    47         super();
    48         this.orderItemId = orderItemId;
    49         this.productId = productId;
    50         this.quantity = quantity;
    51         this.oid = oid;
    52     }
    53     public OrderItem() {
    54         super();
    55     }
    56     
    57 }

    测试:

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

    利用junit进行DemoDao测试

    DemoDaoTest

     1 package com.MavenHibernate.three.Dao;
     2 
     3 import static org.junit.Assert.*;
     4 
     5 import org.junit.Before;
     6 import org.junit.Test;
     7 
     8 import com.MavenHibernate.three.entity.Order;
     9 import com.MavenHibernate.three.entity.OrderItem;
    10 
    11 public class DemoDaoTest {
    12 
    13     private DemoDao demoDao=new DemoDao();
    14     
    15     @Before
    16     public void setUp() throws Exception {
    17     }
    18 
    19     @Test
    20     public void testAddOrder() {
    21         Order order = new Order();
    22         order.setOrderNo("226");
    23         OrderItem oi=null;
    24         for (int i = 0; i < 3; i++) {
    25             oi = new OrderItem();
    26             oi.setProductId(10+i);
    27             oi.setQuantity(20+i);
    28             oi.setOrder(order);
    29             order.getOrderItems().add(oi);
    30             
    31         }
    32         demoDao.addOrder(order);
    33     }
    34 
    35     //订单项
    36     @Test
    37     public void testAddOrderItem() {
    38         Order order = new Order();
    39         order.setOrderId(5);
    40         OrderItem oi=null;
    41         for (int i = 0; i < 3; i++) {
    42             oi = new OrderItem();
    43             oi.setProductId(10+i);
    44             oi.setQuantity(20+i);
    45             oi.setOrder(order);
    46             order.getOrderItems().add(oi);
    47             demoDao.addOrderItem(oi);
    48             
    49         }    
    50     }
    51 
    52     
    53 
    54 }

    结果:

    订单项

     2.懒加载

    DemoDaoTest

    运行时控制台会报一个这样的错误:

    处理方式:(第一种)
    在对应实体映射文件中的关联关系的维护中添加 lazy="false"

    处理方式:(第二种)
       在一对多的实体类中添加属性是否打开懒加载

     在order实体类中

     

     DemoDao中的懒加载方法

     DemoDaoTest

      1 package com.MavenHibernate.three.Dao;
      2 
      3 import static org.junit.Assert.*;
      4 
      5 import java.util.List;
      6 
      7 import org.junit.Before;
      8 import org.junit.Test;
      9 
     10 import com.MavenHibernate.three.entity.Order;
     11 import com.MavenHibernate.three.entity.OrderItem;
     12 
     13 public class DemoDaoTest {
     14 
     15     private DemoDao demoDao=new DemoDao();
     16     
     17  18     public void setUp() throws Exception {
     19     }
     20 
     21     @Test
     22     public void testAddOrder() {
     23         Order order = new Order();
     24         order.setOrderNo("226");
     25         OrderItem oi=null;
     26         for (int i = 0; i < 3; i++) {
     27             oi = new OrderItem();
     28             oi.setProductId(10+i);
     29             oi.setQuantity(20+i);
     30             oi.setOrder(order);
     31             order.getOrderItems().add(oi);
     32             
     33         }
     34         demoDao.addOrder(order);
     35     }
     36 
     37     //订单项
     38     @Test
     39     public void testAddOrderItem() {
     40         Order order = new Order();
     41         order.setOrderId(5);
     42         OrderItem oi=null;
     43         for (int i = 0; i < 3; i++) {
     44             oi = new OrderItem();
     45             oi.setProductId(10+i);
     46             oi.setQuantity(20+i);
     47             oi.setOrder(order);
     48             order.getOrderItems().add(oi);
     49             demoDao.addOrderItem(oi);
     50             
     51         }    
     52     }
     53 
     54     /**
     55      * 关于懒加载的问题
     56      * hibernate3之后出现的
     57      *  failed to lazily initialize a collection of role:
     58      *   com.MavenHibernate.three.entity.Order.orderItems, could not initialize proxy - no Session
     59      *   * orderNo数据来源于t_hibernate_order表
     60      * orderItems数据来源于t_hibernate_order_item表
     61      * 
     62      * 因为两表有关联关系所以不可以分开查询,
     63      * 而hibernate默认的策略是不查询关联关系对应关联表数据的
     64      * 
     65      * 处理方式:(第一种)
     66      * 在对应实体映射文件中的关联关系的维护中添加  lazy="false"
     67      * 如:<bag lazy="false" name="orderItems"  cascade="save-update" inverse="true">
     68      */
     69     
     70 
     71     @Test
     72     public void testGetOrder() {
     73         Order order = new Order();
     74         order.setOrderId(10);
     75         //关闭懒加载
     76         order.setInitChildren(0);
     77         Order o = this.demoDao.getOrder(order);
     78         System.out.println(o.getOrderNo());
     79         System.out.println(o.getOrderItems());
     80     }
     81 
     82     /**
     83      * 查询多个
     84      * 在查询单个中懒加载问题的解决方案
     85      * 会导致在查询多个的时候sql语句也会增多,
     86      * 当查询数据过多的时候导致代码性能变低
     87      * 
     88      * 总:如果将懒加载的功能关闭,即:lazy=false,
     89      * 那么在查询多条订单数据的情况下是非常影响性能的
     90      * 
     91      * 查单个需要关闭懒加载    目的是需要加载出关联表的数据
     92      * 查多个不能关闭懒加载    加载关联表的数据的查询次数过多
     93      * 
     94      * 处理方式:(第二种)
     95      * 在一对多的实体类中添加属性是否打开懒加载
     96      * 
     97      */
     98     @Test
     99     public void testGetOrderList() {
    100         List<Order> orderList = this.demoDao.getOrderList();
    101         for (Order order : orderList) {
    102             System.out.println(order.getOrderNo());
    103 //            System.out.println(order.getOrderItems());
    104         }
    105     }
    106     /**
    107      * 删除订单,关联关系同时删除
    108      */
    109     @Test
    110     public void testDelOrder() {
    111         Order order = new Order();
    112         order.setOrderId(10);
    113         this.demoDao.delOrder(order);
    114     }
    115 
    116 }
  • 相关阅读:
    PHP获取一周的日期
    关系型数据库和非关系型数据库的区别和特点
    关系型数据库和非关系型数据库的特性以及各自的优缺点
    什么是数据库?什么是关系数据库?什么是非关系型数据库?
    PHP中把对象转数组的几个方法
    验证银行卡号
    xss过滤方法
    PHP 随机字符
    计算两个日期相差年月日
    判断一个时间段是否包含周末
  • 原文地址:https://www.cnblogs.com/xcn123/p/11300176.html
Copyright © 2011-2022 走看看