继上文:
1.延迟加载的优势
提高内存的使用率,减少对象占用内存时间
减少用户并发冲突的几率
2.在项目中采用延迟加载操作,一般采用OpenSessionInView 模式控制(避免Session 关闭过早导致延迟实例化异常)
采用Struts2 的Interceptor 控制
采用Servlet 的Filter 控制
public class MyInterceptor implements Interceptor{
public String interceptor(ActionInvocation in){
//追加前期处理逻辑
in.invoke();//调用后续的Action, Result(JSP)组件
//追加后期处理逻辑
session.close();
}
}
*.action -->Struts2 控制器(struts.xml)--> 拦截器(前期处理)
Action,DAO.findById(session.load());
Result(JSP) 通过解析JSP标签和表达式(触发getXXX),加载数据库数据,显示-->拦截器(后期处理,session.close())-->给浏览器响应JSP生成的内容
public class MyFilter implements Filter{
public void doFilter(request, response, chain){
//前期处理逻辑
chain.doFilter(request, response,chain);//调用后续的JSP,Servlet 等组件处理
// 后期处理逻辑
session.close();
}
}
==========采用OpenSessionInView 模式控制Session 关闭===========
◆ 修改HibernateUtil 工具类,采用ThreadLocal 封装Session
◆ 编写一个Interceptor,在in.invoke() 方法后关闭Session,取消原Dao中的session.close()
◆ 在Struts配置中定义Interceptor组件,为某个<action>添加引入时,需要追加defaultStack 的引用
<action name="" class="">
<interceptor-ref name="opensession" />
<interceptor-ref name="defaultStack" />
......
</action>
===========================================================
5.session.get() 和session.load() 的区别和联系
1)两个方法都是按主键做条件查询
2)load 采用延迟加载机制,get 采用立刻加载机制
3)load 方法返回一个动态代理类AutoProxy 对象,get 方法返回原有实体类对象
4)get 未查询出记录返回null, load 未查询出记录抛出ObjectNotFoundException 异常
6.Hibernate 关联映射
如:ACCOUNT -->Account
SERVICE -->Service
关联映射的好处:在实体对象间如果建立了关联映射,可以通过Account 对象获取相关的Service 对象。也可以通过Service 获取相关的Account 对象。
基于关联映射实现根据Account 寻找Service 信息,操作步骤:
1)在Account 方添加一个Set 集合属性,用于存储相关的多个 Service 对象信息,添加setter 和getter 方法
2)在Account.hbm.xml 文件中描述关联属性(Set 集合属性)
<set name="集合属性名">
<key column="指定关联条件中的外键字段名"></key>
<one-to-many class="指定要关联和加载的一方Service" />
</set>
3)使用方法:accounnt.getServices(); 获取当前account 对象相关的Service 对象信息
注意:关联属性数据加载默认采用延迟加载机制,使用中不要过早关闭session.