懒加载
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就一直被占用而不能被释放掉。这也导致本次事务访问的事务比较长,这与“对数据库表中的数据访问的事务尽可能短小”的原则相抵触。
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就一直被占用而不能被释放掉。这也导致本次事务访问的事务比较长,这与“对数据库表中的数据访问的事务尽可能短小”的原则相抵触。
相关文章推荐
- Iframe自适应其加载的内容高度
- 卸载Macfee杀毒软件之后Outlook无法加载项scanotlk.dll,outlook已经将其禁用
- Android有效解决加载大图片时内存溢出的问题
- IE页面后退刷新数据加载问题
- CI的helper的加载
- 利用CSS、JavaScript及Ajax实现图片预加载的三大方法
- java类加载机制
- Android 使用动态加载框架DL进行插件化开发
- Android之批量加载图片OOM问题解决方案
- Android ListView异步加载图片乱序问题,原因分析及解决方案
- maven加载不了 listener
- 翻翻git之---效果鲜明的类ViewPager库 ConvenientBanner(对图片加载部分进行修改)
- 【spring bean】spring中bean的懒加载和depends-on属性设置
- ubuntu系统启动qtceator时提示:Qt5.5.1/Tools/QtCreator/lib/qtcreator/plugins/libHelp.so: 无法加载库
- [转]使用$controllerProvider按需加载controller
- lua代码的加载
- OpenGL -- OBJ 模型加载
- Hibernate延时加载:属性延时加载与关系延时加载
- vue-lazyload图片延迟加载插件的实例讲解
- arcgis中图层加载