您的位置:首页 > 其它

懒加载

2014-05-14 09:43 197 查看
初识懒加载:懒加载是指程序推迟访问数据库,这样做可以保证有时候不必要的访问数据库,因为访问一次数据库是比较耗时的。
1) Load()方法的懒加载:如果在session关闭之前都没有对数据库进行访问或进行对所load的对象进行初始化即:Hibernate. initialize(employeeSet) ,则肯定会报错。因为在为访问数据库之前load()方法懒加载返回的是一个对象的代理,获取它的属性都是获取不到的。但是,如果在session关闭之前访问了数据库或对load的对象进行了初始化,则会强行访问一次数据库进行查询并将真正的对象赋值给代理.
2) one-to-one(元素)懒加载:
此种元素的懒加载使用比较少,因为它对性能的增加表现不明显,因此Hibernate对查询主对象的”一对一”懒加载默认是关闭的。

只有基于外键关联方式的“一对一”才能用懒加载。

实现此种懒加载必须在从对象这边同时满足三个条件:

① lazy!=false(lazy的属性有三个选项分别为:no-proxy、false和proxy;

② Constrained = true ;

③ fetch=select。
注意:

1. 主表不能有constrained=true,所以主表没有懒加载。

2. 不在session关闭之前查询IdCard的属性会报错,但getId()和getClass()除外。

3. 在Person和IdCard“一对一”关联关系中通过知道IdCard的id查对应的IdCard时候,Hibernate只会查IdCard相关的信息(不包括IdCard中person信息),只有在代码中执行像cardId.getPerson()这样访问IdCard里面的属性时候才会查询数据库查其中person相关信息。
4. 因为仅仅是“一对一”关联,即使不用懒加载只不过仅仅多查了一条数据而已,所以性能上看不出有什么大的提高。
举例
Person的映射文件保持不变:

<hibernate-mapping package="cn.itcast.domain">

  <class name="Person">

    <id name="id">

      <generator class="native"/>

    </id>

    <property name="name"/>

    <on
e-to-one name="idCard"/>

  </class>

</hibernate-mapping>
修改IdCard映射文件:
<hibernate-mapping package="cn.itcast.domain">

  <class name="IdCard" table="id_card">

    <id name="id"> 

      <generator class="foreign">

        <param name="property">person</param>

      </generator>

    </id>

    <property name="usefulLife" column="userful_life"/>

    <one-to-one name="person" constrained="true" lazy="proxy" fetch="select"/>

  </class>

</hibernate-mapping>
注意:

1. lazy=”proxy”和fetch=”select”在这里是可以不用写明的,因为Hibernate默认lazy=”proxy” fetch=”select”.

2. lazy的选项proxy表示什么时候加载信息,即:通过代理方式需要加载时候才加载而不是不管需不需要全都加载);fetch的选项select表示通过select方式查询需要的信息,选项join表示通过执行内连接把所有信息统统查出来。
3) One-to-many(元素)懒加载:

这种关联关系执行懒加载对程序执行效率是非常有效的。如果不使用懒加载,在论坛中仅仅想查询某贴主时候,则将会一次性将回帖全部查询出来,这不仅浪费时间也是不必要的查询,所以这里使用懒加载时候需要时候才查这是正确的方案。

  Hibernate默认对one-to-many就是使用的懒加载,但用户也可以取消懒加载操作:

方法一:设置lazy=”false”;

方法二:设置fetch=”join”.
4) Many-to-one(元素)懒加载:
此关联关系的懒加载和one-to-one的懒加载一样都是可要可不要的,因为对执行效率的提高都不是非常明显。
5) Many-to-many(元素)懒加载:

此关联关系的懒加载和one-to-many的懒加载一样对程序的执行效率的提高都是非常明显的。
6) Hibernate默认都是使用懒加载的,如果定义的查询方法 :

static Employee query(int id)中没有对Employee employee =( Employee)session. get(Employee. class, id);中的代理对象idCard没有进行初始化,而在调用此方法时候使用了如下查询操作:

Employee employee =query(1);

System.out.println(employee. getDept(). getName());

这样肯定会出错,因为session关闭前没有初始化Employee,难道要在static Employee query(int id)中加上Hibernate. initialize(employee)进行代理初始化?

我们知道如果不使用懒加载而在程序中不查employee中的Department对象属性,这样会很浪费资源的。
(1) 解决方法一:修改query()方法为:

static Employee query(int id, boolean deptIncluded)

{

  Session session=null;

  Session=HibernateUtil.getSession();

  Employee employee=(Employee)session.get(Employee.class, id);

  If(deptIncluded)

    Hibernate. initialize(employee);

  Return employee;

}

以后调用query()方法是多加一个参数用来指定是否需要初始化代理对象。
(2) 解决方法二:使用OpenSessionInView:
import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import org.hibernate.HibernateException;

import cn.itcast.util.HibernateUtil;

public class HibernateSessionUtilFilter implements Filter

{

  protected FilterConfig filterConfig=null;

  public HibernateSessionUtilFilter()

  {

  

  }

  @Override

       public void destroy()

  {

    this.filterConfig=null;

  }

    @Override

  public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException

  {

    try

    {

      chain.doFilter(request, response);

    }

     finally

     {

       try

       {

         HibernateUtil.commitTransaction();

       }

       catch(HibernateException he)

       {

         HibernateUtil.rollbackTransaction();

       }

       finally

       {

         System.out.println("closeSession已经被执行");

         HibernateUtil.closeSession();

       }

     }

   }

   @Override

   public void init(FilterConfig filterConfig) throws ServletException

   {

     this.filterConfig=filterConfig;

   }

}
最后不要忘记在配置文件中配置此filter。

注意:尽管“Open Session In View”能够解决Hibernate框架的延迟初始化中的Session关闭问题,但也有副作用:如果用户的请求的流程中某一步被阻塞,那在这期间的Session就一直被占用而不能被释放掉。这也导致本次事务访问的事务比较长,这与“对数据库表中的数据访问的事务尽可能短小”的原则相抵触。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  懒加载 load hibernate