Hibernate的抓取策略

立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get()
延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()

类级别检索和关联级别检索
  类级别的检索:<class>标签上配置lazy
  关联级别的检索:<set>/<many-to-one>上面的lazy

从一的一方关联多的一方(<set>
  fetch:控制sql语句的类型
    join :发送迫切左外连接的SQL查询关联对象.fetch=”join”那么lazy被忽略了.
    select :默认值,发送多条SQL查询关联对象.
    subselect :发送子查询查询关联对象.(需要使用Query接口测试)

  lazy:控制关联对象的检索是否采用延迟.
    true :默认值, 查询关联对象的时候使用延迟检索
    false :查询关联对象的时候不使用延迟检索.
    extra :及其懒惰.

  ***** 如果fetch是join的情况,lazy属性将会忽略

在多的一方关联一的一方(<many-to-one>
  fetch:控制SQL语句发送格式
    join :发送一个迫切左外连接查询关联对象.fetch=”join”,lay属性会被忽略.
    select :发送多条SQL检索关联对象.
  lazy:关联对象检索的时候,是否采用延迟
    false :不延迟
    proxy :使用代理.检索订单额时候,是否马上检索客户 由Customer对象的映射文件中<class>上lazy属性来决定.
    no-proxy :不使用代理(不研究)

实例:

/*
 *  区分立即检索和延迟检索
 */
// 立即检索
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);
/*
 *  <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.getOrders().size());// 又发送一条SQL 去查询客户的关联的订单
  tx.commit();
  session.close();}
@Test
/*
 *  <set>配置fetch="join" lazy就会被忽略!!!
 *      * 直接发送迫切左外连接查询两个表.
 */
public void demo3(){
  Session session = HibernateUtils.openSession();
  Transaction tx = session.beginTransaction();
  // 直接发送一条迫切左外连接
  /*
   *   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="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="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);
        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);
        // hibernate发送select count(*) from orders where cno = ?;
        System.out.println(customer.getOrders().size());
        // 发送查询订单的SQL
        for (Order order : customer.getOrders()) {
            System.out.println(order);
        }
        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();
    }
   /*
     * 没有在<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();
    }
   /*
     * 在<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();
    }
   /*
     * 在<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();
    }
  /*
     * 批量抓取
     *     在客户一端配置
     *     <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());
            }
        }
        tx.commit();
        session.close();
    }
/*
     * 批量抓取
     *     通过订单批量抓取客户:
     *         需要在客户一端<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());
        }
        tx.commit();
        session.close();
    }
时间: 2024-08-03 05:42:46

Hibernate的抓取策略的相关文章

Hibernate fetch 抓取策略

上一篇文章(Hibernate的延迟加载 ,懒加载,lazy)说到Hibernate的延迟加载跟fetch的配置还有一定关系,下面就来讨论下fetch的用法. 抓取策略(fetch)是指当我们去查询一个对象里面所关联的其他对象时,按照哪种方法去抓取关联对象. fetch策略一共有四种:select.subselect.join.batch,下面我们一一介绍.我们还是用上面介绍延迟加载的相关表和实体类. Company表: Employee表(employee_company_id为外键) Com

S2JH Hibernate Lazy抓取策略--could not initialize prox

在做 图片上传 相关实体保存时,出现了该错误. 相关Entity     @OneToMany(mappedBy = "objectSid", cascade = CascadeType.ALL, orphanRemoval = true)     @OrderBy("orderIndex desc")     public List<ObjectR2Pic> getShopPagePics() {         return shopPagePics

八 Hibernate延迟加载&amp;抓取策略(优化)

面试:Hibernate效率很低,如何优化? 缓存怎么弄的,语句怎么优化? 聊聊一级缓存,聊聊抓取策略和延迟加载,聊聊批量抓取 延迟加载: 一般不单独使用,和延迟加载一起使用 延迟加载:lazy(懒加载) 执行到该行代码的时候不会发送语句,真正使用这个对象的属性的时候才会发送sql语句进行查询. 类级别延迟加载:指的是是通过load方法查询某个对象的时候是否采用延迟,通过class标签上的lazy来配置. 让类级别延迟加载失效:1 lazy设为false 2 final修饰 3 调用Hibern

hibernate查询&amp;抓取策略优化机制

一 HQL查询 1 一次存1个客户,10个联系人.执行三次,存3个客户,30个联系人,为分页查询做准备 @Test //来3个客户,30个联系人 public void demo1(){ Session session=HibernateUtils.getCurrentSession(); Transaction tx=session.beginTransaction(); Customer customer=new Customer(); customer.setCust_name("小白&q

Hibernate优化---抓取策略

1.延迟加载 类的延迟加载 在类的映射文件中的class标签上配置lazy属性:默认为true,当你配置为false的时候,就算你使用session.load他也会在你调用这个方法之后发送SQL语句,而不是在你使用查询得到的对象的时候才发送SQL语句 关联级别的延迟加载 在类的映射文件中的set和many-to-one上配置lazy属性:默认为true,也就是说,当你查询某个对象是,他不会连带着查询他的关联对象,当你使用这些关联对象的时候才会发送SQL语句查询 2.抓取策略 set上的fetch

Hibernate之抓取策略

时间:2017-1-23 19:08 --区分延迟和立即检索 1.立即检索    当执行某行代码时,会马上发出SQL语句进行查询.    例如:get() 2.延迟检索    当执行某行代码时,不会马上发出SQL语句,只有当真正使用对象时,才会向数据库发出SQL语句.    例如:load() 3.示例代码    /* * 区分立即检索和延迟检索 */ public void fun1(){ Session session = HibernateUtils.openSession(); Tran

hibernate抓取策略学习

一.hibernate抓取策略概述 Hibernate抓取策略(fetching strategy)是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略.抓取策略可以在O/R映射的元数据中声明,也可以在特定的HQL 或条件查询(Criteria Query)中重载声明. 需要注意的是:hibernate的抓取策略只影响get load 方法,对hql是不影响的. 二.hibernate 抓取策略分类 hibernate有如下

Hibernate 优化技术之抓取策略(Fetching strategies)

一.前言 转载请标明出处:http://blog.csdn.net/wlwlwlwl015/article/details/42705585 使用hibernate一年多了,一直觉得他是一个很好用的持久层框架,在处理含有多个复杂的关联关系的数据表时,hibernate提供的各种关联映射可以让我们用少量的代码快速.便捷的去维护各种外键关系,当然他的核心还是允许我们以"面向对象"的方式去操作数据表,因为我们的Java语言就是面向对象的,所以我们使用ORM的持久层框架应该更容易理解和上手,他

【Hibernate 8】Hibernate的调优方法:抓取策略

在上一篇博客中,介绍了Hibernate的缓存机制.合理的配置缓存,可以极大程度上优化Hibernate的性能.这篇博客,介绍另外一个调优方式:抓取策略. 一.什么是抓取策略 抓取策略(fetching strategy):当应用程序需要在关联关系间进行导航的时候,Hibernate如何获取关联对象的策略.抓取策略可以在O / R映射的元数据中声明,也可以在特定的HQL或条件查询(Criteria Query)中重载声明. 二.Hibernate的抓取策略 在Hibernate中,主要包括四种抓