- 浏览: 1499522 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
大多数情况下,Session 管理的目标聚焦于通过合理的设计,避免Session 的频繁创建 和销毁,从而避免大量的内存开销和频繁的JVM垃圾回收,保证系统高效平滑运行。 在各种Session 管理方案中, ThreadLocal 模式得到了大量使用。ThreadLocal 是 Java中一种较为特殊的线程绑定机制。通过ThreadLocal存取的数据,总是与当前线程相关, 也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制。 首先,我们需要知道,SessionFactory负责创建Session,SessionFactory是线程 安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取Session 实例。而 Session并非线程安全,也就是说,如果多个线程同时使用一个Session实例进行数据存取, 则将会导致Session 数据存取逻辑混乱。下面是一个典型的Servlet,我们试图通过一个类 变量session实现Session的重用,以避免每次操作都要重新创建: public class TestServlet extends HttpServlet { private Session session; public void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { session = getSession(); doSomething(); session.flush(); } public void doSomething(){ ......//基于session的存取操作 } } 代码看上去正确无误,甚至在我们单机测试的时候可能也不会发生什么问题,但这样的代 码一旦编译部署到实际运行环境中,接踵而来的莫名其妙的错误很可能会使得我们摸不找头脑。 问题出在哪里? 首先,Servlet 运行是多线程的,而应用服务器并不会为每个线程都创建一个Servlet 实例,也就是说,TestServlet在应用服务器中只有一个实例(在Tomcat中是这样,其他的 应用服务器可能有不同的实现),而这个实例会被许多个线程并发调用,doGet 方法也将被不 同的线程反复调用,可想而知,每次调用doGet 方法,这个唯一的TestServlet 实例的 session 变量都会被重置,线程A 的运行过程中,其他的线程如果也被执行,那么session 的引用将发生改变,之后线程A 再调用session,可能此时的session 与其之前所用的 session就不再一致,显然,错误也就不期而至。 ThreadLocal的出现,使得这个问题迎刃而解。 我们对上面的例子进行一些小小的修改: public class TestServlet extends HttpServlet { private ThreadLocal localSession = new ThreadLocal(); public void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { localSession.set(getSession()); doSomething(); session.flush(); } public void doSomething(){ Session session = (Session)localSession.get(); ......//基于session的存取操作 } } 可以看到,localSession 是一个ThreadLocal 类型的对象,在doGet 方法中,我们 通过其set 方法将获取的session 实例保存,而在doSomething 方法中,通过get 方法取 出session实例。 这也就是ThreadLocal的独特之处,它会为每个线程维护一个私有的变量空间。实际上, 其实现原理是在JVM 中维护一个Map,这个Map的key 就是当前的线程对象,而value则是 线程通过ThreadLocal.set方法保存的对象实例。当线程调用ThreadLocal.get方法时, ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回。 这样,ThreadLocal通过以各个线程对象的引用作为区分,从而将不同线程的变量隔离开 来。 回到上面的例子,通过应用ThreadLocal 机制,线程A 的session 实例只能为线程A 所用,同样,其他线程的session实例也各自从属于自己的线程。这样,我们就实现了线程安 全的Session共享机制。 Hibernate官方开发手册的示例中,提供了一个通过ThreadLocal维护Session的好 榜样: public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (HibernateException ex) { throw new RuntimeException( "Configuration problem: " + ex.getMessage(), ex ); } } public static final ThreadLocal session = new ThreadLocal(); public static Session currentSession() throws HibernateException { Session s = (Session) session.get(); // Open a new Session, if this Thread has none yet if (s == null) { s = sessionFactory.openSession(); session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); session.set(null); if (s != null) s.close(); } } 在代码中,只要借助上面这个工具类获取Session 实例,我们就可以实现线程范围内的 Session 共享,从而避免了在线程中频繁的创建和销毁Session 实例。不过注意在线程结束 时关闭Session。 同时值得一提的是,新版本的Hibernate在处理Session的时候已经内置了延迟加载机 制,只有在真正发生数据库操作的时候,才会从数据库连接池获取数据库连接,我们不必过于担 心Session的共享会导致整个线程生命周期内数据库连接被持续占用。 上面的HibernateUtil类可以应用在任何类型的Java程序中。特别的,对于Web程序 而言,我们可以借助Servlet2.3规范中新引入的Filter机制,轻松实现线程生命周期内的 Session管理(关于Filter的具体描述,请参考Servlet2.3规范)。 Filter的生命周期贯穿了其所覆盖的Servlet(JSP也可以看作是一种特殊的Servlet) 及其底层对象。Filter在Servlet被调用之前执行,在Servlet调用结束之后结束。因此, 在Filter 中管理Session 对于Web 程序而言就显得水到渠成。下面是一个通过Filter 进 行Session管理的典型案例: public class PersistenceFilter implements Filter { protected static ThreadLocal hibernateHolder = new ThreadLocal(); public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { hibernateHolder.set(getSession()); try { …… chain.doFilter(request, response); …… } finally { Session sess = (Session)hibernateHolder.get(); if (sess != null) { hibernateHolder.set(null); try { sess.close(); } catch (HibernateException ex) { throw new ServletException(ex); } } } } …… } 通过在doFilter中获取和关闭Session,并在周期内运行的所有对象(Filter链中其 余的Filter,及其覆盖的Servlet 和其他对象)对此Session 实例进行重用,保证了一个 Http Request处理过程中只占用一个Session,提高了整体性能表现。 在实际设计中,Session的重用做到线程级别一般已经足够,企图通过HttpSession实 现用户级的Session重用反而可能导致其他的问题。凡事不能过火,Session重用也一样。
发表评论
-
自定义用户类(UserType)的使用
2011-08-04 10:46 1854学习hibernate有段时间了,最近复习这门技术时看到了自定 ... -
技巧:利于ThreadLocal模式管理Session
2011-08-02 10:31 1263在利用Hibernate开发DAO模块时,我们和Session ... -
Hibernate中的回调与拦截机制
2011-07-27 17:31 1459在某些情况下,我们需要对实体的CURD操作进行捕获并执行一些操 ... -
HibernateTemplate中HibernateCallback的事务
2011-07-04 14:41 1439目的:使用HibernateTemplate执行execute ... -
Hibernate的复杂用法HibernateCallback
2011-07-04 14:40 1334HibernateTemplate还提供一种更加灵活的方式来操 ... -
Hibernate session FlushMode有五种属性
2011-07-04 13:59 17261、NEVER:已经废弃了,被MANUAL取代了2 MANUA ... -
详解Hibernate Session
2011-07-01 22:42 1486这里介绍Hibernate Session,Ses ... -
HttpSession与Hibernate中Session的区别
2011-07-01 22:41 1288一、javax.servlet.http.HttpSess ... -
巧用SQLQuery中的addScalar
2011-06-02 17:16 5740当我们用HQL进行子查询的时候,如select * from ... -
hibernate中SQLQuery的addEntity();方法
2011-04-13 14:48 2887如果使用原生sql语句进行query查询时,hibernate ... -
Hibernate的clear(),flush(),evict()方法详解
2011-03-24 11:18 17691.Clear 方法 无论是Load 还是 G ... -
hibernate模糊查询-Restrictions.ilike & Expression.like
2011-03-11 10:32 16350Criteria criteria = session.c ... -
Hibernate分页查询小结
2011-03-10 11:14 1824通常使用的Hibernate通常是三种:hql查询,QBC查询 ... -
current_session_context_class
2011-03-07 15:31 1291此设置的作用如下: What does sessionFac ... -
Hibernate的拦截器和监听器
2010-12-14 15:06 1383核心提示:最近项目需要,用到了Hibernate的拦截器和 ... -
孙卫琴.精通Hibernate:Java对象持久化技术详解_触发器使缓存与数据库不一致
2010-12-14 08:46 1382p198 -
孙卫琴.精通Hibernate:Java对象持久化技术详解_优化报表查询的性能
2010-12-13 17:51 1267p332 -
孙卫琴.精通Hibernate:Java对象持久化技术详解_查询结果类型
2010-12-13 17:34 1300p329 -
孙卫琴.精通Hibernate:Java对象持久化技术详解_投影查询
2010-12-13 17:31 1420p325 -
深入浅出hibernate_夏昕_hibernate别名完成ResultSet和实体的映射
2010-12-13 17:09 1351p199
相关推荐
根据提供的文件信息,“精通Hibernate3.0—Java数据库持久层开发实践(付京周)”这一书籍主要聚焦于使用Hibernate框架进行Java应用的数据库持久层开发。本书旨在帮助读者深入理解并掌握Hibernate的核心概念和技术...
精通hibernate3.0--java数据库持久层开发实践(付京周) 分两卷下载,需要积分共1分。谢谢 精通hibernate3.0--java数据库持久层开发实践(付京周) 分两卷下载,需要积分共1分。谢谢
HIBERNATE+-+符合Java习惯的关系数据库持久化
标题 "钢炮级 持久层 —— 中篇" 提到的是关于持久层技术的深入探讨,这通常指的是在软件开发中用于处理数据库交互的框架或库。持久层是应用程序与数据库之间的桥梁,它负责数据的存储和检索,使得业务逻辑与数据...
EJB+JPA数据库持久层开发实践详解.pdf 完整版
Session是Hibernate中的核心接口,它充当了应用程序和数据库之间的桥梁,负责对象的持久化操作,如保存、更新、删除和查询等。Session通常在一个事务中打开并在事务结束时关闭,以确保数据的一致性和完整性。 然而...
《Hibernate执行持久层访问步骤详解...以上就是Hibernate执行持久层访问的基本步骤,掌握这些知识点,能帮助开发者高效地进行数据库操作。在实际开发中,还需要结合具体业务需求灵活运用,不断优化代码,提升系统性能。
具体来说,当一个Java对象被持久化到数据库时,Hibernate会自动执行必要的SQL语句来插入或更新数据库中的记录;当从数据库加载对象时,Hibernate则会根据查询结果构建相应的Java对象实例。 ### Hibernate的优势 1....
在Java的持久化框架中,Hibernate是一个非常流行的ORM(对象关系映射)工具,它使得开发者可以使用面向对象的方式来操作数据库。"重写hibernate的session简单增删改查"是一个针对初学者的实践教程,旨在帮助理解如何...
HIBERNATE - 符合Java习惯的关系数据库持久化.htm
2. **DAO(Data Access Object)模式**:在业务层与持久层之间创建一个抽象层,用于执行数据库操作,方便Struts与Hibernate的交互。 3. **模型驱动**:Struts2支持模型驱动的方式,可以直接使用Hibernate的实体对象...
8.2 根据数据库定义生成映射文件——MiddleGen 8.3 Hibernate官方工具 8.4 XDoclet-同步Hibernate基础代码 8.5 工具的使用周期 第9章 Hibernate XDoclet模板配置 9.1 IDEA 9.2 Eclipse 第10章 Hibernate益友...
本文将深入探讨Hibernate中的核心概念——Session管理。 首先,理解Session在Hibernate中的角色至关重要。Session是Hibernate的主要工作单元,它是应用程序与数据库之间的桥梁。它负责保存、检索和更新Java对象,...
即支持对象式的操作也支持SQL操作,整个持久层的使用除了需要配置数据库连接外,无需其它配置,使用上比HIBERNATE/MYBIATIS更简单,而功能与这些知名的数据库持久层相近。
在实际应用中,我们通常会将`SessionFactory`和`Session`的管理封装到DAO(Data Access Object)层,以便于业务逻辑层调用。同时,为了优化性能,Hibernate还提供了二级缓存,可以通过配置将频繁访问的数据存储在...
在Java的持久化框架Hibernate中,`Session`和`Transaction`是两个至关重要的概念,它们在数据管理和事务处理中起到核心作用。这篇文章将深入解析这两个概念及其相关知识点。 `Session`是Hibernate提供的一种与...
在本篇《junit学习(十)——Spring与Hibernate整合的单元测试》中,我们将探讨如何在Java开发中,利用JUnit进行Spring和Hibernate框架的集成测试。单元测试是软件开发中的重要环节,它能帮助开发者确保代码的质量和...
**Hibernate:符合JAVA习惯的关系数据库持久化** Hibernate是一款强大的Java对象关系映射(ORM)框架,它极大地简化了Java应用程序与关系数据库之间的交互。通过提供一套API和元数据描述,Hibernate能够将Java类与...
Hibernate也是目前Java开发中最为流行的数据库持久层框架,现已归JBOSS所有。 它的设计目标是将软件开发人员从大量相同的数据持久层相关编程工作中解放出来。无论是从设计草案还是从一个遗留数据库开
在基于持久层框架的DAO(Data Access Object)模式应用中,Hibernate扮演着核心角色,使得业务逻辑和数据访问逻辑分离,提高了代码的可复用性和可维护性。 1. **DAO模式的理解** DAO模式是一种设计模式,它创建了...