day36 08-Hibernate抓取策略:批量抓取

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
    /*
     *批量抓取  减少与数据库交互的次数
     *  通过订单批量抓取客户:
     *       需要在客户一端<class>标签上配置batch-size
     * 批量抓取都是在一的一端配置的
     */
      public void demo13(){
          Session session = HibernateUtils.openSession();
          Transaction tx = session.beginTransaction();
          List<Order> list =session.createQuery("from Order").list();
          for (Order order : list) {
            System.out.println(order.getCustomer().getCname());
        }
      }
    @Test
    /*
     *批量抓取  减少与数据库交互的次数
     *  在客户的一端配置
     *  <set>集合上配置batch-size="3"
     */
      public void demo12(){
          Session session = HibernateUtils.openSession();
          Transaction tx = session.beginTransaction();
          List<Customer> list =session.createQuery("from Customer").list();
          for (Customer customer : list) {
            for (Order order : customer.getOrders()) {
                System.out.println(order.getAddr());
            }
        }
      }
      @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 package="cn.itcast.vo"><!-- 如果这里配置了包名下面可以不用写 -->
<!--
<hibernate-mapping>
-->
<!--  
    <class name="cn.itcast.hibernate3.demo2.Customer" table="customer">
    -->
    <!-- 
    <class name="cn.itcast.vo.Customer" table="customer">
        -->
            <class name="Customer" batch-size="2" table="customer">
        <!-- 配置唯一标识 -->
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="cname" column="cname" length="30"/>
        
        <!-- 建立映射 -->
        <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
        <!-- 这里把级联去掉  要最简短的配置 
        <set name="orders" cascade="save-update" inverse="true">
-->
<set name="orders" cascade="save-update" batch-size="2">
            <!-- <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>
<?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  name="customer" column="cno" class="cn.itcast.vo.Customer"/>
    
    </class>
</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 + "]";
    }

}

原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6702378.html