java

位置:IT落伍者 >> java >> 浏览文章

单Hibernate实现OpenSessionInView


发布日期:2021年08月11日
 
单Hibernate实现OpenSessionInView
OpenSessionInViewInview是什么?

OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类其主要意思是在发起一个页面请求时打开Hibernate的Session一直保持这个Session直到这个请求结束具体是通过一个Filter来实现的

当然在我的理解OpenSessionInView是Hibernate的一种模式因为官方也给出了相关代码

JBoss的OpenSessionInView的地址

OpenSessionInView简单来说就是在请求到达View时Session不关闭可以方便的调用Session中的方法由于Hibernate引入了Lazy特性使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值Hibernate会抛出一个LazyLoad的Exception所以为了解决这个问题Spring和Hibernate都给出了相应的解决方案

Spring的方案是一个过滤器只需要你配置就OK了

但是我目前公司的项目用的是单Hibernate一个框架以前公司未解决懒加载问题将所有的关联对象的lazy全部设为false这样大大降低了系统的运行效率为了解决这个问题自动翻阅资料找到了Hibernate官方的OpenSessionInView模式此模式是一个Filter

package monhibernate;import javaioIOException;import javaxservletFilter;import javaxservletFilterChain;import javaxservletFilterConfig;import javaxservletServletException;import javaxservletServletRequest;import javaxservletServletResponse;import orghibernateSessionFactory;import orghibernateStaleObjectStateException;/* * Hibernate的OpenSessionInView过滤器可以实现在页面中Session依旧不关闭解决懒加载带来的副作用可以随意使用懒加载提升系统效率 * * @author wurt * */public class HibernateSessionRequestFilter implements Filter {

private SessionFactory sf;

public void doFilter(ServletRequest request

ServletResponse response

FilterChain chain)

throws IOException ServletException {

try {

//开启Session和Transcation在Hibernate查询中需要用getCurrentSession获取当前Session

sfgetCurrentSession()beginTransaction()

// 放行

chaindoFilter(request response)

// Session提交getCurrentSession获取的Session会在提交之后自动关闭

sfgetCurrentSession()getTransaction()commit()

} catch (StaleObjectStateException staleEx) {

throw staleEx;

} catch (Throwable ex) {

// Rollback only

exprintStackTrace()

try {

//如果Transcation依旧存在回滚

if (sfgetCurrentSession()getTransaction()isActive()) {

sfgetCurrentSession()getTransaction()rollback()

}

} catch (Throwable rbEx) {

rbExprintStackTrace()

}

// Let others handle it… maybe another interceptor for exceptions?

throw new ServletException(ex)

}

}

public void init(FilterConfig filterConfig) throws ServletException {

// sessionFactory 可以通过自己的代码获取此值

sf = HibernateSimpleDaosessionFactory;

}

public void destroy() {} }

将此过滤器配置到webxml一切问题都解决了

配制方法如下

<filter>

<filtername>HibernateSessionInView</filtername>

<filterclass>monhibernateHibernateSessionRequestFilter</filterclass></filter><filtermapping>

<filtername>HibernateSessionInView</filtername>

<urlpattern>/*</urlpattern></filtermapping>

然后将公司中Hibernate配置文件的lazy全部去掉一切OK

之前lazy=fasle的情况下载入Hibernate需要查询+甚至更多的SQL然而采用OpenSessionInView仅仅需要条(门户网站首页)

为什么会有这么大的提升?

之前的SQL是不管用不用只要是false全部查出来再说

现在的lazy都是true在初次查询时只会查询实体需要的字段而不会查询关联的对象当在View中需要关联时才会去查询数据库

lazy=true + OpenSessionInView可以避免很多不是必要的查询速度自然会有所提升

使用注意事项

在Dao中无需再创建Transcation因为过滤器已经创建好

使用Session请使用getCurrentSession来获取得到当前的Session而不是openSession新建一个Session

通过getCurrentSession获得的Session无需关闭因为在过滤器提交时会自动关闭

示例代码仅仅贴出一个方法

public List<T> getAll(Class T)

{

Session session = getCurrentSession()

List<T> list = null;

try{

list = sessioncreateQuery(from + TgetName())list()

return list;

}catch (RuntimeException e){

throw e;

} }

上一篇:如何在java中操作word

下一篇:Java网络数据库编程及其应用