zoukankan      html  css  js  c++  java
  • day36 07-Hibernate抓取策略:many-to-one上的抓取策略

    package cn.itcast.test;
    
    import java.util.List;
    
    import org.hibernate.Hibernate;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import cn.itcast.utils.HibernateUtils;
    import cn.itcast.vo.Customer;
    import cn.itcast.vo.Order;
    
    /**
     * Hibernate的抓取策略
     * @author zhongzh
     *
     */
    public class HibernateDemo2 {
          @Test
          /*
           * 没有在<many-to-one>标签上配置:
           *   * fetch="select" lazy="proxy"
           *        *  发送多条SQL
           */
          public void demo11(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
              // 在这行发送多条SQL 查询关联对象.
              Order order = (Order) session.get(Order.class, 1);
              System.out.println(order.getCustomer().getCname());
              tx.commit();
              session.close();
          }
          @Test
          /*
           * 没有在<many-to-one>标签上配置:
           *   * fetch="select" lazy="false"
           *        *  发送多条SQL
           */
          public void demo10(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
              // 在这行发送多条SQL 查询关联对象.
              Order order = (Order) session.get(Order.class, 1);
              System.out.println(order.getCustomer().getCname());
              tx.commit();
              session.close();
          }
        
          @Test
          /*
           * 没有在<many-to-one>标签上配置:
           *   * fetch="join" lazy="被忽略"
           *   * 发送迫切左外连接
           */
          public void demo9(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
              //发送一条迫切左外连接.查询关联对象.
              Order order = (Order) session.get(Order.class, 1);
              System.out.println(order.getCustomer().getCname());
              tx.commit();
              session.close();
          }
        
          @Test
          /*
           * 没有在<many-to-one>标签上配置:
           *   * 发送多条SQL进行查询.
           * 
           */
          public void demo8(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
              //只会发送一条查询订单的SQL.
              Order order = (Order) session.get(Order.class, 1);
              
              //使用订单的客户对象的时候,又发送一条SQL查询订单关联的客户
              System.out.println(order.getCustomer().getCname());
              tx.commit();
              session.close();
          }
        
        
           @Test
           /*
            * 在<set>集合上配置
            *   * fetch="subselect"  lazy="true"
            *        * 使用subselect的时候 需要使用query接口进行测试.
            *        * 如果查询一个客户 查询多个客户.
            *   如果有多个客户:
            *   * select * from orders where cno in (1,2,3);
            *   如果只有一个客户:
            *   * select * from orders where cno = 1;
            */
           public void demo7(){
               
               Session session =  HibernateUtils.openSession();
               Transaction tx =  session.beginTransaction();
              
               List<Customer> list = session.createQuery("from Customer").list();
               
               for (Customer customer : list) {
                System.out.println(customer.getOrders().size());
            }
                 
                 tx.commit();
                 session.close();
               
           }
           @Test
           /*
            * 在<set>集合上配置
            *   * fetch="select"  lazy="extra"
            *   * lazy:extra:极其懒惰.要订单的数量
            */
           public void demo6(){
               
               Session session =  HibernateUtils.openSession();
               Transaction tx =  session.beginTransaction();
                 Customer customer = (Customer) session.get(Customer.class, 1);
                 // select count(*) from orders where cno = ?; 
                 System.out.println(customer.getOrders().size());
                 //发送查询订单的SQL.
                 for (Order order : customer.getOrders()) {
                    System.out.println(order);//使用订单的是时候它才会发送查询订单的SQL.
                }
                 
                 tx.commit();
                 session.close();
               
           }
           @Test
           /*
            * 在<set>集合上配置
            *   * fetch="select"  lazy="false"
            *   * lazy:false:关联对象的检索不使用延迟
            */
           public void demo5(){
               
               Session session =  HibernateUtils.openSession();
               Transaction tx =  session.beginTransaction();
               //  发送多条SQL,查询关联对象.
                 Customer customer = (Customer) session.get(Customer.class, 1);
                 //  使用订单的时候又发送一条查询这个客户的订单的SQL
                 System.out.println(customer.getOrders().size());
                 
                 
                 tx.commit();
                 session.close();
               
           }
       @Test
       /*
        * 在<set>集合上配置
        *   * fetch="select"  lazy="true"
        *   * lazy:true-使用延迟检索
        *   * 发送多条SQL,查询关联对象
        */
       public void demo4(){
           
           Session session =  HibernateUtils.openSession();
           Transaction tx =  session.beginTransaction();
           //  发送一条只查询客户的SQL
             Customer customer = (Customer) session.get(Customer.class, 1);
             //  使用订单的时候又发送一条查询这个客户的订单的SQL
             System.out.println(customer.getOrders().size());
             
             
             tx.commit();
             session.close();
           
       }
       @Test
     /*
      * 
      * <set>配置fetch="join" lazy就会被忽略!!!!    
      *            *  发送迫切左外连接查询两个表.
      */
     public void demo3(){
         
         Session session = HibernateUtils.openSession();
         Transaction tx = session.beginTransaction();
         //直接发送一条迫切左外连接。其实迫切左外连接和左外连接的SQL语句是一样的.只不过封装的对象不一样.
         //迫切左外连接封装到一个对象里.而普通左外连接封装到一个数组里.
         //只要一查客户订单就出来了.
         /*
          * Hibernate: 
        select
            customer0_.cid as cid0_1_,
            customer0_.cname as cname0_1_,
            orders1_.cno as cno0_3_,
            orders1_.oid as oid3_,
            orders1_.oid as oid1_0_,
            orders1_.addr as addr1_0_,
            orders1_.cno as cno1_0_ 
        from
            Customer customer0_ 
        left outer join
            orders orders1_ 
                on customer0_.cid=orders1_.cno 
        where
            customer0_.cid=?
    
          */
         Customer customer = (Customer) session.get(Customer.class, 1);
         
         System.out.println(customer.getOrders().size());
         
         
         tx.commit();
         session.close();
         
     }
        
        
      @Test
      /*
       * 
       * <set>没有配置fetch 和 lazy情况
       * 
       */
      public void demo2(){
          Session session = HibernateUtils.openSession();
          Transaction tx = session.beginTransaction();
          
          Customer customer = (Customer) session.get(Customer.class,1);// 发送查询客户的SQL.
          //System.out.println(customer.getCname());
          
          System.out.println(customer.getOrders().size());// 使用了客户的订单的时候,才会发送查询订单的SQL. 又发送一条SQL 去查询客户的关联的订单.
          tx.commit();
          session.close();
      }
        
     
       @Test
       /*区分立即检索和延迟检索
       *
       *
       */
       public void demo1(){
    
               Session session = HibernateUtils.openSession();
               Transaction tx  = session.beginTransaction();
               
              //立即检索
               //
    /*           Customer customer = (Customer) session.get(Customer.class, 1);
               System.out.println(customer);*/
               //延迟检索:
               // 持久化类如果设置为final 延迟检索就失效了.因为不能生成代理对象
               // 在Customer.hbm.xml中在<class>标签上配置lazy="false"不支持延迟检索,就会立即检索.
                          Customer customer = (Customer) session.load(Customer.class, 1);//这是类级别的检索
               //System.out.println(customer);//如果这一行注释的话根本就不会发送SQL语句,你执行完了它也不会发送,因为你根本没有
                          //用到它里面的属性。
               //初始化代理对象  发送SQL语句  产生代理对象  那肯定就能拿出来了
               //System.out.println(customer.getCname());
               
               //还可以这样来初始化代理对象  
                          Hibernate.initialize(customer);//当你初始化的时候它才会发送SQL语句
                          tx.commit();
               session.close();
               
           }
           
       }

    <?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="cn.itcast.hibernate3.demo2.Order" table="orders">
    -->
    <class name="cn.itcast.vo.Order" table="orders">
    <!-- 配置唯一标识 -->
    <id name="oid" column="oid">
    <generator class="native"/>
    </id>
    <!-- 配置普通属性 -->
    <property name="addr" column="addr" length="50"/>
    <!-- 配置映射 -->
    <!--
    <many-to-one>标签
    name :关联对象的属性的名称.
    column :表中的外键名称.
    class :关联对象类的全路径
    -->
    <!--
    <many-to-one name="customer" column="cno" class="cn.itcast.hibernate3.demo2.Customer"/>
    -->
    <many-to-one fetch="select" lazy="proxy" name="customer" column="cno" class="cn.itcast.vo.Customer"/>

    </class>
    </hibernate-mapping>



    <?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 package="cn.itcast.vo"><!-- 如果这里配置了包名下面可以不用写 --> <!-- <hibernate-mapping> --> <!-- <class name="cn.itcast.hibernate3.demo2.Customer" table="customer"> --> <!-- <class name="cn.itcast.vo.Customer"> --> <class name="Customer" lazy="true"> <!-- 配置唯一标识 --> <id name="cid" column="cid"> <generator class="native"/> </id> <!-- 配置普通属性 --> <property name="cname" column="cname" length="20"/> <!-- 建立映射 --> <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. --> <!-- 这里把级联去掉 要最简短的配置 <set name="orders" cascade="save-update" inverse="true"> --> <set name="orders" cascade="save-update" > <!-- <key>标签中column:用来描述一对多多的一方的外键的名称. --> <key column="cno"></key> <!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 --> <!-- <one-to-many class="cn.itcast.hibernate3.demo2.Order"/> --> <one-to-many class="cn.itcast.vo.Order"/> </set> </class> <!-- 命名查询的方式 --> <query name="findAll"> from Customer </query> <!-- 这里要写sql语句 <sql-query> </sql-query> --> </hibernate-mapping>
    package cn.itcast.vo;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * 客户的实体:
     * @author 姜涛
     *
     */
    public class Customer {
        private Integer cid;
        private String cname;
        
        
        
        
        public Customer() {//无参构造函数
            super();
            // TODO Auto-generated constructor stub
        }
        
        
        public Customer(String cname) {//有参构造
            super();
            this.cname = cname;
        }
    
    
        // 一个客户有多个订单.
        private Set<Order> orders = new HashSet<Order>();
        public Integer getCid() {
            return cid;
        }
        public void setCid(Integer cid) {
            this.cid = cid;
        }
        public String getCname() {
            return cname;
        }
        public void setCname(String cname) {
            this.cname = cname;
        }
        public Set<Order> getOrders() {
            return orders;
        }
        public void setOrders(Set<Order> orders) {
            this.orders = orders;
        }
        //@Override
    /*    public String toString() {//客户这里打印也打印出订单的集合。这是死循环了,所以这里应该去掉一方的打印。
            return "Customer [cid=" + cid + ", cname=" + cname + ", orders="
                    + orders + "]";
                return "Customer [cid=" + cid + ", cname=" + cname + "]";//客户这里去掉订单集合的打印
            
        }*/
        //测试迫切内连接的封装效果。重写toString()方法
        @Override
        public String toString() {
            return "Customer [cid=" + cid + ", cname=" + cname + ", orders="
                    + orders + "]";
        }
    }
    package cn.itcast.vo;
    /**
     * 订单的实体:
     * @author 姜涛
     *
     */
    public class Order {
        private Integer oid;
        private String addr;
        // 订单属于某一个客户.放置一个客户的对象.
        private Customer customer;
        public Integer getOid() {
            return oid;
        }
        public void setOid(Integer oid) {
            this.oid = oid;
        }
        public String getAddr() {
            return addr;
        }
        public void setAddr(String addr) {
            this.addr = addr;
        }
        public Customer getCustomer() {
            return customer;
        }
        public void setCustomer(Customer customer) {
            this.customer = customer;
        }
        //@Override
    /*    public String toString() {//订单这边又打印客户了。这是死循环了,所以这里应该去掉一方的打印。
            return "Order [oid=" + oid + ", addr=" + addr + ", customer="
                    + customer + "]";
        }*/
        //测试迫切内连接的封装效果。重写toString()方法
        @Override
        public String toString() {//两边不能同时打印,不然容易出问题
            return "Order [oid=" + oid + ", addr=" + addr + "]";
        }
    
    }
  • 相关阅读:
    都说程序员钱多空少,程序员真的忙到没时间回信息了吗?
    C/C++知识分享: 函数指针与指针函数,看完这篇你还能不懂?
    C++的那些事儿:从电饭煲到火箭,C++无处不在
    年薪90万程序员不如月入3800公务员?安稳与高收入,到底如何选择?
    【C++学习笔记】C++ 标准库 std::thread 的简单使用,一文搞定还不简单?
    C语言既有高级语言又有低级语言的特点,但为什么它不是低级语言呢?
    【C++学习笔记】看完这篇,C++ 的链接问题不怕你搞不明白!
    既然C++这么难学,为什么还有人“自讨苦吃”?
    编程语言这么多,为什么就只有C 语言能一直得到 SQLite 的青睐?
    初学者疑惑:C语言中,函数反复调用会有什么问题?
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6702187.html
Copyright © 2011-2022 走看看