Hibernate性能优化之————延迟加载与抓取策略

 

Hibernate性能优化之————延迟加载与抓取策略

 

懒加载【延迟加载】:

主要目的:

为了推迟与数据库交互的时间,提高系统的系能

它是hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据才会创建

实现方式:

Hibernate中主要通过代理(proxy)机制来实现延迟加载

延迟加载的具体过程:

Hibernate从数据库获取某一个对象数据时、获取某一个对象的集合属性值时、获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据(除标识符值外),Hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只有在真正需要使用该对象的数据时才创建这个真实的对象,真正的从数据库中加载它的数据。这样在某些情况下,就可以提高查询效率。

 

注:Session的load()方法对实体的加载默认采用延迟加载(get()方法默认采用立即加载)。

 

Hibernate中默认采用延迟加载的情况主要有:

1、  当调用Session上的load()方法加载一个实体时,会采用延迟加载

2、  当Session加载某个实体时,会对这个实体中的集合属性值采用延迟加载

3、  当Session加载某一个实体时,会对这个实体所单端关联(one-to-one , many-to-one)的另一个实体对象采用延迟加载

 

在Hibernate中想要通过修改配置文件来启用或关闭延迟加载功能的方法有:

1、  在加载单个实体,如果不需要延迟加载,就可以使用Session的get()方法

2、  当Session加载某个实体时,不需要对这个实体中的集合属性值延迟加载、而是要立即加载。这时可以在映射文件中针对这个集合的配置元素(<set>、<bag>、<list>……)添加属性lazy=false

3、  当加载Session加载某个实体时,不需要对这个实体所单端关联的另一个实体对象延迟加载,就可以在映射文件中针对这个单端关联的配置元素(<one-to-one>、<many-to-one>)添加属性lazy=false

 

返回代理对象【可以理解为一种快捷方式】: User_$$_javassist_7【代理对象是不会为空的】

User user=(User)session.load(clazz,id);

User_$$_javassist_7与User类型不同,为什么没有抛异常?

Hibernate在执行过程中动态的创建了User类的子类User_$$_javassist_7,通过这个子类创建了代理对象

 

代理对象限制:和代理对象关联的session对象关闭之前使用

S.load()懒加载,并不是立刻去访问数据库,返回的是一个代理对象

通过代理对象访问数据库

 

User.getName会输出一条插入语句一句查询语句

User.getId();,User.getClass();只输出一条插入语句【不访问数据库也会得到,所有不会让代理对象访问数据库】

 

单端关联(<one-to-one>、<many-to-one>)上的抓取策略

可以给单端关联的映射元素添加fetch属性。Fetch属性有两个可选值

1、  select:作为默认值,它的策略是当需要使用到关联对象的数据时,另外单独发送一条select语句抓取当前对象的关联对象的数据,即延迟加载

2、  join:它的策略是在同一条SELECT语句使用内连接来获得对象的数据和它的关联对象的数据。此时关联对象的延迟加载失败

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping

    package="com.hbsi.domain">

<!-- 映射持久化类 -->

<class name="Order" table="order">

    <!-- 映射对象标识符 -->

    <id name="id" column="id">

       <generator class="native"></generator>

    </id>

    <!-- 映射普通属性 -->

    <property name="orderNo"/>

    <property name="createdTime" column="create_time type="timestamp"/>

    <!-- 映射多对一关联,添加fetch属性 -->

    <many-to-one name="account" column="account_id" fetch="join" not-null="true"/>

</class>

</hibernate-mapping>

 

集合属性上的抓取策略:

在属性集合的映射元素上可以添加fetch属性,它有三个可选值

1、  select:作为默认值,它的策略是当需要使用所关联集合的数据时,另外单独发送一天SELECT语句抓取当前对象的关联集合,即延迟加载

2、  join:在同一条SELECT语句使用内连接来获得对象的关联集合,此时关联集合上的lazy会失效

3、  subselect:另外发送一条查询语句(或子查询语句)抓取在前面查询到的所有实体对象的关联集合。这个策略对HQL的查询也起作用

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping

    package="com.hbsi.domain">

<!-- 映射持久化类 -->

<class name="Account" table="account">

    <!-- 映射对象标识符 -->

    <id name="id" column="id">

       <generator class="native"></generator>

    </id>

    <!-- 映射普通属性 -->

    <property name="lginName" column="login_name"/>

    <!—用集合来映射一对多关联,并指定fetch属性 -->

    <set name=”orderSet” cascade=”all” inverse=”true” fetch=”subselect”>

       <key column=”account_id”/>

       <one-to-many class=”Order”/>

</set >

</class>

</hibernate-mapping>

 

一对一的关联关系:

当我们查询的是主对象时,将person和idcard左外连接查询出person对象和idcard对象时,没有懒加载

当我们查询的是从对象时,对于idcard所关联的person对象是懒加载的

 

Lazy的取值有:false【懒加载功能取消】、proxy【用代理对象】、true

 

Lazy:指相关联的属性,什么时候去抓取

Fetch:通过什么方式来进行抓取。Selsect二次select语句查询

                                          Join连接查询,lazy属性失效

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值