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

     什么是关联(association)
       关联指的是类之间的引用关系。如果类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框架、以面向对象的思想操作数据库
       实体类--》表
       属性--》字段

    关联的分类:关联可以分为一对一、一对多/多对一、多对多关联
          关联是有方向的
      
       订单表、订单项表

       select * from t_order t,t_orderItem m where t.oid = m.oid
       and .....
       
       
       class Order{
      private STIRNG OID;
      ...
      private Set<OrderItem> OrderItems; 
       }
       
       session.get(Order.class,1)

    我们先导入映射文件并且创建对应的实体类建立关联关系

    Order.hbm.xml

    <?xml version="1.0" encoding="UTF-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 name="com.huang.three.entity.Order" table="t_hibernate_order">
            <id name="orderId" type="java.lang.Integer" column="order_id">
                <generator class="increment" />
            </id>
            <property name="orderNo" type="java.lang.String" column="order_no">
            </property>
            <!-- 需要在映射文件中进行关联关系的维护  这里描述的是一对多的关系  -->
            <bag name="orderItems" cascade="save-update" inverse="true">
                <!-- 从表的外键 -->
                <key column="oid"></key>
                <!-- 查询从表数据,然后形成list集合填充到orderItems -->
                <one-to-many class="com.huang.three.entity.OrderItem" />
                <!-- 
                    select * from t_hibernate_order_item where oid=1
                 -->
            </bag>
        </class>
    </hibernate-mapping>

      Order

    package com.huang.three.entity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Order {
    
        private Integer orderId;
        private String orderNo;
        private List<OrderItem> orderItems=new ArrayList<>();
        private Integer ininChildren=1;//代表开启懒加载,0代表关闭懒加载
        
        
        public Integer getIninChildren() {
            return ininChildren;
        }
        public void setIninChildren(Integer ininChildren) {
            this.ininChildren = ininChildren;
        }
        public List<OrderItem> getOrderItems() {
            return orderItems;
        }
        public void setOrderItems(List<OrderItem> orderItems) {
            this.orderItems = orderItems;
        }
        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;
        }
        @Override
        public String toString() {
            return "Order [orderId=" + orderId + ", orderNo=" + orderNo + ", orderItems=" + orderItems + "]";
        }
        public Order(Integer orderId, String orderNo, List<OrderItem> orderItems) {
            super();
            this.orderId = orderId;
            this.orderNo = orderNo;
            this.orderItems = orderItems;
        }
        public Order() {
            super();
        }
        
    }

    OrderItem.hbm.xml

    <?xml version="1.0" encoding="UTF-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 name="com.huang.three.entity.OrderItem" table="t_hibernate_order_item">
            <id name="orderItemId" type="java.lang.Integer" column="order_item_id">
                <generator class="increment" />
            </id>
            <property name="productId" type="java.lang.Integer" column="product_id">
            </property>
            <property name="quantity" type="java.lang.Integer" column="quantity">
            </property>
            <property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false">
            </property>
            <!-- 需要在映射文件中进行关联关系的维护  这里描述的是多对一的关系  -->
            <many-to-one name="order" class="com.huang.three.entity.Order" column="oid"></many-to-one>
        </class>
    </hibernate-mapping>

      OrderItem

    package com.huang.three.entity;
    
    public class OrderItem {
    
        private Integer orderItemId;
        private Integer productId;
        private Integer quantity;
        private Integer oid;
        private Order order;
        
        
        public Order getOrder() {
            return order;
        }
        public void setOrder(Order order) {
            this.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 OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid, Order order) {
            super();
            this.orderItemId = orderItemId;
            this.productId = productId;
            this.quantity = quantity;
            this.oid = oid;
            this.order = order;
        }
        public OrderItem() {
            super();
       }
    }

    然后在hibernate.hbm.xml添加实体映射文件

    测试:

    DemoDao

    package com.huang.three.dao;
    
    import java.util.List;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.huang.three.entity.Order;
    import com.huang.three.entity.OrderItem;
    import com.huang.two.util.SessionFactoryUtils;
    
    
    public class DemoDao {
        /**
         * 为了测试关系型映射文件配置准确
         *     讲解insert=false,update=false的用途
         * @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(0).equals(order.getIninChildren())) {
    //            0代表了程序员想要关闭懒加载,也就意味着需要强制加载关联关系对象
                Hibernate.initialize(o.getOrderItems());
    //            System.out.println(o.getOrderItems());
            }
            transaction.commit();
            session.close();
            return o;
        }
        
        public List<Order> getOrderList() {
            Session session = SessionFactoryUtils.openSession();
            Transaction transaction = session.beginTransaction();
            List<Order> 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

    package com.huang.three.dao;
    
    import static org.junit.Assert.*;
    
    import java.util.List;
    
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.huang.three.entity.Order;
    import com.huang.three.entity.OrderItem;
    public class DemoDaoTest {
        private DemoDao demoDao=new DemoDao(); 
    
        @Test
        public void testAddOrder() {
            Order order=new Order();
            order.setOrderNo("p9");
            OrderItem oi=null;
            for (int i = 0; i < 3; i++) {
                oi=new OrderItem();  
                oi.setProductId(10+i);
                oi.setQuantity(20+i); 
                oi.setOrder(order);
                order.getOrderItems().add(oi);
            }
            demoDao.addOrder(order);
    //        demoDao.addOrderItem(orderItem);
            
        }


    @Test
    public void testAddOrderItem() { Order order=new Order(); order.setOrderId(5); OrderItem oi=null; for (int i = 0; i < 3; i++) { oi=new OrderItem(); oi.setProductId(10+i); oi.setQuantity(20+i); oi.setOrder(order); order.getOrderItems().add(oi); demoDao.addOrderItem(oi); } }
    /** * 关于懒加载的问题 * hibernate3之后出现的 * * failed to lazily initialize a collection of role: * com.huang.three.entity.Order.orderItems, * could not initialize proxy - no Session * orderNo数据来源于t_hibernate_order * orderItems数据来源于t_hibernate_order_item * * 查一张表的效率高还是两张 * 一张 * * hibernate默认的策略:是不查询关联关系对应关联表数据的 * */ @Test public void testGetOrder() { Order order=new Order(); order.setOrderId(10); order.setIninChildren(0); Order o=this.demoDao.getOrder(order); System.out.println(o.getOrderNo()); System.out.println(o.getOrderItems()); } /** * 如果说将懒加载的功能关闭,也就是lazy=false.那么在查询多条订单数据的情况下是非常影响性能的 * * 查单个需要关闭懒加载 目的是需要加载出关联表的数据 * 查多个不能关闭懒加载 加载关联表的数据查询次数过多 */ @Test public void testGetOrderList() { List<Order> orderlist=this.demoDao.getOrderList(); for (Order order : orderlist) { System.out.println(order.getOrderNo()); // System.out.println(order.getOrderItems()); } } @Test public void testDelOrder() { Order order=new Order(); order.setOrderId(5); this.demoDao.delOrder(order); } }

    hibernate的懒加载


          如果说将懒加载的功能关闭,也就是lazy=false.那么在查询多条订单数据的情况下是非常影响性能的
         
              查单个需要关闭懒加载        目的是需要加载出关联表的数据
              查多个不能关闭懒加载        加载关联表的数据查询次数过多

    我们在Order中写入:

    private Integer ininChildren=1;//代表开启懒加载,0代表关闭懒加载

    将DemoDao修改

    if(o != null && new Integer(0).equals(order.getIninChildren())) {
    //            0代表了程序员想要关闭懒加载,也就意味着需要强制加载关联关系对象
                Hibernate.initialize(o.getOrderItems());
            }

     

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

    }

    删除调用testDelOrder方法

    @Test

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

    }

  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/bf6rc9qu/p/11300068.html
Copyright © 2011-2022 走看看