zoukankan      html  css  js  c++  java
  • [转]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. }  
  • 相关阅读:
    详解事件驱动跟消息驱动机制相比
    浏览器加载 CommonJS 模块的原理与实现
    全面理解 javascript 的 argements caller callee call apply 之caller
    在javaScript中检测数据类型的几种方式
    Netbeans IDE 安装Emmet插件并解决Emmet插件无效果问题
    JS的 try catch使用心得
    safari 浏览器 input textarea select 等不能响应用户输入
    js十大排序算法
    js实现 页面加载 完成 后顺序 执行
    原生JS封装 toast 弹层,自动关闭
  • 原文地址:https://www.cnblogs.com/ZhuRenWang/p/4690719.html
Copyright © 2011-2022 走看看