[转]OpenSessionInView模式

OpenSessionInView模式解决的问题:
  * hibernate事物边界问题
  * 因session关闭导致hibernate延迟加载例外的问题

事物边界:
    一个事物的完成应该是在业务层完成的,但是事物的创建却是在数据层来做,这样必定造成业务层和数据层耦合性增强。

延迟加载例外:
     如你所知,延迟加载使用了动态代理机制,只有在真正使用这个对象的时候才会去访问数据库,但是如果在数据层进行了事物提交,session关闭,再去访问 数据就会导致延迟加载例外异常,所以我们必须加大session的生命周期,在访问数据之后关闭session。

因此我们可以通过OpenSessionInView模式来解决上面的问题


OpenSessionInView模式需要用到一个非常重要的一个类:ThreadLocal

OpenSessionInView模式:
  * 需要构建一个过滤器,把事物的创建及提交放在过滤器里进行。
  * 加大session的有效范围,把session放在当前线程里(ThreadLocal),使session在当前线程内有效,并且在当前线程内访问的是同一个session。

OpenSessionInView模式缺点:
  *并发性减弱
  *内存消耗加大

1.实体类:
Java代码  收藏代码
  1. package com.yx.zzg.pojo;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class User {  
  6.       
  7.     private String id;  
  8.   
  9.     private String username;  
  10.   
  11.     private String password;  
  12.   
  13.     private Date createTime;  
  14.   
  15.     private Date endTime;  
  16.   
  17.     public String getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(String id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     public String getUsername() {  
  26.         return username;  
  27.     }  
  28.   
  29.     public void setUsername(String username) {  
  30.         this.username = username;  
  31.     }  
  32.   
  33.     public String getPassword() {  
  34.         return password;  
  35.     }  
  36.   
  37.     public void setPassword(String password) {  
  38.         this.password = password;  
  39.     }  
  40.   
  41.     public Date getCreateTime() {  
  42.         return createTime;  
  43.     }  
  44.   
  45.     public void setCreateTime(Date createTime) {  
  46.         this.createTime = createTime;  
  47.     }  
  48.   
  49.     public Date getEndTime() {  
  50.         return endTime;  
  51.     }  
  52.   
  53.     public void setEndTime(Date endTime) {  
  54.         this.endTime = endTime;  
  55.     }  
  56. }  


2.映射文件:
Java代码  收藏代码
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC   
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.     "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  5. <hibernate-mapping package="com.yx.zzg.pojo">  
  6.     <class name="User" table="t_user">  
  7.         <id name="id">  
  8.             <!-- 指定主键生成策略 -->  
  9.             <generator class="uuid" />  
  10.         </id>  
  11.         <property name="username" unique-key="true" />  
  12.         <property name="password" />  
  13.         <property name="createTime" />  
  14.         <property name="endTime" />  
  15.     </class>  
  16.   
  17. </hibernate-mapping>  


3.提供一个过滤器:
Java代码  收藏代码
  1. package com.yx.zzg.servelt;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11.   
  12. import org.hibernate.Session;  
  13. import org.hibernate.Transaction;  
  14.   
  15. import com.yx.zzg.util.HibernateUtil;  
  16.   
  17. public class OpenSessionInView implements Filter {  
  18.   
  19.     public void destroy() {  
  20.   
  21.     }  
  22.   
  23.     public void doFilter(ServletRequest request, ServletResponse response,  
  24.             FilterChain filter) throws IOException, ServletException {  
  25.         Transaction tx = null;  
  26.         Session session = null;  
  27.         try {  
  28.             session = HibernateUtil.getThreadLocalSession();  
  29.             tx = session.beginTransaction();  
  30.             filter.doFilter(request, response);  
  31.             tx.commit();  
  32.         } catch (Exception e) {  
  33.             if (tx != null) {  
  34.                 tx.rollback();  
  35.                 throw new RuntimeException(e.getMessage(),e);  
  36.             }  
  37.         } finally {  
  38.             HibernateUtil.colseSession();  
  39.         }  
  40.     }  
  41.   
  42.     public void init(FilterConfig arg0) throws ServletException {  
  43.   
  44.     }  
  45.   
  46. }  


4.web.xml中配置过滤器
Java代码  收藏代码
  1. <filter>  
  2.         <filter-name>OpenSessionInView</filter-name>  
  3.         <filter-class>com.yx.zzg.servelt.OpenSessionInView</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>OpenSessionInView</filter-name>  
  7.         <url-pattern>/*</url-pattern>  
  8.     </filter-mapping>  


5.HibernateUtil类:
Java代码  收藏代码
  1. package com.yx.zzg.util;  
  2.   
  3. import org.hibernate.Session;  
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.cfg.Configuration;  
  6.   
  7. public class HibernateUtil {  
  8.       
  9.     private static SessionFactory sessionFactory;  
  10.   
  11.     //创建一个ThreadLocal对象  
  12.     private static ThreadLocal threadSession = new ThreadLocal();  
  13.   
  14.     private HibernateUtil() {  
  15.   
  16.     }  
  17.   
  18.     static {  
  19.         Configuration cfg = new Configuration().configure();  
  20.         sessionFactory = cfg.buildSessionFactory();  
  21.     }  
  22.   
  23.     /** 
  24.      * 从当前线程中获取session,如果没有,则得到session,并将此session放入当前线程中 
  25.      * @return 
  26.      */  
  27.     public static Session getThreadLocalSession() {  
  28.         Session session = (Session) threadSession.get();  
  29.         if (session == null) {  
  30.             session = getSession();  
  31.             threadSession.set(session);  
  32.         }  
  33.         return session;  
  34.     }  
  35.   
  36.     /** 
  37.      * 关闭session,并将当前线程中的session设置为null 
  38.      */  
  39.     public static void colseSession() {  
  40.         Session session = (Session) threadSession.get();  
  41.         if (session != null) {  
  42.             session.close();  
  43.             threadSession.set(null);  
  44.         }  
  45.     }  
  46.   
  47.     public static Session getSession() {  
  48.         return sessionFactory.openSession();  
  49.     }  
  50.   
  51. }  


6.数据层方法:
Java代码  收藏代码
  1. public User findUserById(String id) {  
  2.     User user = (User) HibernateUtil.getThreadLocalSession().load(  
  3.             User.class, id);  
  4.     return user;  
  5. }  
原文地址:https://www.cnblogs.com/ZhuRenWang/p/4690719.html