zoukankan      html  css  js  c++  java
  • 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                 }
  • 相关阅读:
    centos 安装 TortoiseSVN svn 客户端
    linux 定时任务 日志记录
    centos6.5 安装PHP7.0支持nginx
    linux root 用户 定时任务添加
    composer 一些使用说明
    laravel cookie写入
    laravel composer 安装指定版本以及基本的配置
    mysql 删除重复记录语句
    linux php redis 扩展安装
    linux php 安装 memcache 扩展
  • 原文地址:https://www.cnblogs.com/AluoKa/p/11191455.html
Copyright © 2011-2022 走看看