计算机教程

当前位置:3522.com > 计算机教程 > hibernate的延迟加载和抓取策略3522.com

hibernate的延迟加载和抓取策略3522.com

来源:http://www.4sports-uk.com 作者:3522.com 时间:2019-10-06 07:45

hibernate框架学习笔记12:查询优化,hibernate学习笔记

类级别查询优化:

创建一个实体类:

3522.com 1

package domain;

import java.util.HashSet;
import java.util.Set;

//客户实体
public class Customer {

    private Long cust_id;
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    //使用set集合,表达一对多关系
    private Set<LinkMan> linkMens = new HashSet<LinkMan>();

    public Set<LinkMan> getLinkMens() {
        return linkMens;
    }
    public void setLinkMens(Set<LinkMan> linkMens) {
        this.linkMens = linkMens;
    }
    public Long getCust_id() {
        return cust_id;
    }
    public void setCust_id(Long cust_id) {
        this.cust_id = cust_id;
    }
    public String getCust_name() {
        return cust_name;
    }
    public void setCust_name(String cust_name) {
        this.cust_name = cust_name;
    }
    public String getCust_source() {
        return cust_source;
    }
    public void setCust_source(String cust_source) {
        this.cust_source = cust_source;
    }
    public String getCust_industry() {
        return cust_industry;
    }
    public void setCust_industry(String cust_industry) {
        this.cust_industry = cust_industry;
    }
    public String getCust_level() {
        return cust_level;
    }
    public void setCust_level(String cust_level) {
        this.cust_level = cust_level;
    }
    public String getCust_linkman() {
        return cust_linkman;
    }
    public void setCust_linkman(String cust_linkman) {
        this.cust_linkman = cust_linkman;
    }
    public String getCust_phone() {
        return cust_phone;
    }
    public void setCust_phone(String cust_phone) {
        this.cust_phone = cust_phone;
    }
    public String getCust_mobile() {
        return cust_mobile;
    }
    public void setCust_mobile(String cust_mobile) {
        this.cust_mobile = cust_mobile;
    }
    @Override
    public String toString() {
        return "Customer [cust_id="   cust_id   ", cust_name="   cust_name   "]";
    }
}

View Code

 

自定义工具类:

3522.com 2

package utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory sf;

    static{
        //1 创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2 根据配置信息,创建 SessionFactory对象
         sf = conf.buildSessionFactory();
    }

    //获得session => 获得全新session
    public static Session openSession(){
                //3 获得session
                Session session = sf.openSession();

                return session;

    }
    //获得session => 获得与线程绑定的session
    public static Session getCurrentSession(){
        //3 获得session
        Session session = sf.getCurrentSession();

        return session;
    }    
}

View Code

 

 

测试类示例:

package lazy;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import domain.Customer;
import utils.HibernateUtils;

//懒加载|延迟加载
public class Demo {

    @Test
    // get方法 : 立即加载.执行方法时立即发送sql语句查询结果
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------

        Customer c = session.get(Customer.class, 2l);

        System.out.println(c);
        //----------------------------------------------------
        tx.commit();
        session.close();

    }

    @Test
    // load方法(默认):是在执行时,不发送任何sql语句.返回一个对象.使用该对象时,才执行查询.
    // 延迟加载: 仅仅获得没有使用.不会查询.在使用时才进行查询.
    // 是否对类进行延迟加载: 可以在配置文件中通过在class元素上配置lazy属性来控制.
        //lazy:true  加载时,不查询.使用时才查询b
        //lazy:false 加载时立即查询.
    public void fun2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------

        Customer c = session.load(Customer.class, 2l);

        //----------------------------------------------------
        tx.commit();
        session.close();
        System.out.println(c);

    }

}

 

为了提高效率,建议使用延迟加载,要确保调用属性时候,session是打开的,否则会报出异常

 

 

关联级别优化:

 

配置文件:集合的属性配置

lazy属性: 决定是否延迟加载
true(默认值): 延迟加载,懒加载
false: 立即加载
extra: 极其懒惰

fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
select(默认值): 单表查询加载
join: 使用多表查询加载集合
subselect:使用子查询加载集合

结论:为了提高效率.fetch的选择上应选择select. lazy的取值应选择 true. 全部使用默认值.

 

http://www.bkjia.com/Javabc/1305335.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javabc/1305335.htmlTechArticlehibernate框架学习笔记12:查询优化,hibernate学习笔记 类级别查询优化: 创建一个实体类: package domain; import java.util.HashSet; import java.util.Se...

一,延迟加载    

    1、实体类延迟加载 通过代理机制完成,由javassist类库实现运行时代理,修改实体类的字节码实现了运行时代理
        <class lazy="true|false">
        实体级别的延迟加载默认值为true,意味实体对象是延迟加载,只影响load方法。
         <class lazy="true|false">其他查询方式都是立即加载
    
          2、关联属性延迟加载 默认情况下除了<one-to-one>之外所有的关联属性都是延迟加载
          A、单端关联对象<many-to-one lazy="proxy|no-proxy|false"> <one-to-one lazy="false|proxy|no-proxy">
             通过javassist代理实现延迟加载
     
          B、集合关联对象 <set lazy="true|extra|false">
             在hibernate中为实现集合关联属性的延迟加载,没有使用jdk中的集合框架,它实现了一套自己的集合框架,
              比如它的set集合通过PersistSet(该类实现java.util.Set接口)实现,
           集合关联属性的lazy默认值为true,意味集合关联属性延迟加载。
     
              lazy="extra"除指定集合属性延迟加载功能外,能够让hibernate智能感知开发者对关联的集合属性的操作类型,
               hibernate会根据开发者对集合操作类型不同执行不同的sql语句,所以建议集合关联属性的lazy="extra"         

1          Department dept = (Department) session.get(Department.class, 10);
2         
3         Set<Employee> set = dept.getEmps();//获取到关联的集合属性
4         
5         //判断集合中元素个数是否为0 当关联属性lazy="true",如果我们仅仅需要判断集合中是否元素或者仅仅需要集合中元素个数不是这些元素
6         // select * from emp where deptno=?
7         boolean b = set.isEmpty();
8         //获取集合中元素的个数
9         int size = set.size();

 

 1         Department dept = (Department) session.get(Department.class, 10);
 2         
 3         Set<Employee> set = dept.getEmps();//获取到关联的集合属性
 4         
 5         //当lazy="extra"时,集合关联属性延迟加载,同时提供了一些功能,让hibernate能够智能感应开发者对集合关联属性的操作类型
 6         //hibernate会根据开发者对集合属性的操作类型不同执行不同的sql语句
 7         //当开发者执行调用集合属性的isEmpty()方法或者size()方法时发送select count(*) from emp where deptno=?
 8         //当开发者执行遍历操作发送select * from emp where deptno=?
 9         boolean b = set.isEmpty();
10     
11         int size = set.size();

 

     
      3、普通属性延迟加载 编译时对字节码进行修改
        <property lazy="false|proxy|no-proxy">

 

  关联对象的延迟加载有利于程序的运行效率,但在一些情况下会产生问题,如:延迟加载的关联对象在session关闭后如何获取?

  1. openSessionInView,把session的生命周期延长,保证在获取关联对象后关闭session;
  2. 在HQL语句中使用关键字fetch左外连接查询,立即获取主体对象和关联对象          

    List list=session.createQuery("from Employee e join fetch e.dept").list(); //Employee(dept)

     3. 在关联属性映射信息中将fetch="join",会通过左外连接立即把关联对象查询出来(不建议使用)

    4. 通过Hibernate工具类中initialize(Object lazyObject),立即加载关联对象 

    5. Criteria获取关联对象,调用setFetchMode("关联对象名",FetchMode m)将抓取方式m设置FetchMode.JOIN

    

 

 

二,抓取策略

  关联对象的抓取方式的设置:

      <many-to-one fetch="select|join">和<one-to-one fetch="join|select">

      <set fetch="select|join|subselect">

  join : 以左外连接形式立即获取关联对象(仅仅针对get方法和load方法时有效,对HQL查询、标准查询无效,不推荐设置)。
    select :另外发送一条查询语句获取关联对象
      subselect :另外发送一条查询语句或者子查询获取关联对象加载出来

  

本文由3522.com发布于计算机教程,转载请注明出处:hibernate的延迟加载和抓取策略3522.com

关键词: 3522.com

上一篇:Ubuntu查看和写入系统日志

下一篇:没有了