hibernate增删改查一般使用getcurrentsession还是opensession写增删改查?current是不是会占

[转载]hibernate中getCurrentSession()和openSession()区别
getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭(调用session的close()方法)
这里getCurrentSession本地事务(本地事务:jdbc)时
要在配置文件里进行如下设置&
* 如果使用的是本地事务(jdbc事务)
name="hibernate.current_session_context_class"&thread&/property&
* 如果使用的是全局事务(jta事务)
name="hibernate.current_session_context_class"&jta&/property&
(这个不能忘记,我在测试中如果没有上面在hibernate.cfg.xml中配置,使用getCurrentSession()时,会出错(org.hibernate.HibernateException:
No CurrentSessionContext configured!)
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext
,在 getCurrentSession() 被调用的时候,实际被执行的方法是
CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前
Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以
getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。为了账号安全,请及时绑定邮箱和手机
openSession和getCurrentSession
是不是 openSession() session不管释不释放 下一个session都只能再新建一个连接对象connection?
而getCurrentSession 只要一提交事物 连接就自动释放 下一个session就不用新建connection 也能使用原有的connection
而且用getCurrentSession同时建的两个session 使用的也是同一个connection? 求大神帮忙梳理一下 我有点乱了
好像是这样 我好想记得同时用getCurrentSession() 建两个session 这两个session本身就是相同的 所以connection 也一样 是不是这样啊
应该是,getCurrentSession()方法本来就是获取现有的session,所以创建的两个session,本质是一个session,用的是同一个connection
非常感谢!
写下你的评论...
Copyright (C)
All Rights Reserved | 京ICP备 号-2java中Hibernate session在service实现事务getCurrentSession()和openSession()区别-Java基础-Jsp教程-壹聚教程网java中Hibernate session在service实现事务getCurrentSession()和openSession()区别
本文章为各位详细的介绍了java中Hibernate session在service实现事务getCurrentSession()和openSession()区别,并且拿了很多的例子进行对比了,希望文章能够为各位带来帮助。
当我们在使用Hibernate作为操作的类库时,我们一般在DAO层里与的操作,把业务逻辑写在service层里。但是如果我们的项目比较小,那么直接在dao层里写事务也是可以的,这个就是看个人了,没有什么特别的规定。但是如果项目比较大,那么DAO应该只做单纯的数据库的操作,service写事务的操作,即整个业务逻辑。
例如:业务逻辑要求向数据库中的用户表增加一个用户,同时向日志表中加入一条日志,而这需要调用DAO的两个方法(UserDao的saveUser和LogDao的saveLog)。这显然是一个事务,也就是如果一个操作出现了问题,就要回滚到初始的状态。那么如何在Service层控制事务呢,本文就以此例的代码说明。
在DAO进行Session事务出现的问题
我们先看看在DAO层里写Hibernate的session的事务。
package com.
import org.hibernate.SessionF
import org.hibernate.cfg.C
public class HibernateUtil {
&&& private static final SessionFactory sessionFactory = buildSessionFactory();
&&& private static SessionFactory buildSessionFactory() {
&&&&&&& try {
&&&&&&&&&&& // Create the SessionFactory from hibernate.cfg.xml
&&&&&&&&&&& return new Configuration().configure().buildSessionFactory();
(Throwable ex) {
&&&&&&&&&&& // Make sure you log the exception, as it might be swallowed
&&&&&&&&&&& System.err.println(&Initial SessionFactory creation failed.& + ex);
&&&&&&&&&&& throw new ExceptionInInitializerError(ex);
&&& public static SessionFactory getSessionFactory() {
&&&&&&& return sessionF
创建用户表T_user(id,username)和日志表T_log(id,content),以及它们对应的实体类User、Log及映射文件,这里就不一一贴出代码。
public class UserDao {
&&& public void saveUser(User user){
&&&&&&& SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory
&&&&&&& Session session = sessionFactory.openSession();// openSession
&&&&&&& session.beginTransaction(); //开始事务
&&&&&&& session.save(user);
&&&&&&& session.getTransaction().commit(); //事务提交
&&&&&&& session.close(); //关闭session
public class LogDao {
&&& public void saveLog(Log log){
&&&&&&& SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory
&&&&&&& Session session = sessionFactory.openSession();// openSession
&&&&&&& session.beginTransaction(); //开始事务
&&&&&&& session.save(log);
&&&&&&& session.getTransaction().commit(); //事务提交
&&&&&&& session.close(); //关闭session
接下来我们看看在service中写一个业务逻辑
public class TestService {
&&& public void save(User user){
&&&&&&& UserDao userDao = new UserDao();
&&&&&&& userDao.saveUser(user);
&&&&&&& LogDao logDao = new LogDao();
&&&&&&& Log log = new Log();
&&&&&&& log.setContent(&插入一个用户&);
&&&&&&& logDao.saveLog(log);
可以看到,我们在两个DAO里写了数据库的事务,代码中高亮显示了,session.beginTransaction()显示声明事务的开始。
这样写是不对的,因为这两个事情作为一个事务来进行的,会出现一个事务成功提交,而另外一个可能提交失败,导致不一致的情况,这样这两个操作不算是一个事务transaction,所以这么写就是一个失败的事务。
因此,我们要将事务在service中进行声明。
在service层写session的数据库事务
为了将事务放在service中,我们需要更改HibernateUtil的代码才能实现。否则使用上面的那个不能达到我们的需求。在这个新的HibernateUtil代码中,利用了ThreadLocal的线程内的局部变量来保存hibernate的session对象。这样就可以在不同的class中使用同一个session对象,而不用传递参数。
public class HibernateUtil {
&&& public static final ThreadLocal session = new ThreadLocal();
&&& public static final SessionFactory sessionF
&&& static {
&&&&&&& try {
&&&&&&&&&&& sessionFactory = new Configuration().configure().buildSessionFactory();
&&&&&&& } catch ( Throwable ex ) {
&&&&&&&&&&& throw new ExceptionInInitializerError( ex );
&&& public static Session currentSession() throws HibernateException
&&&&&&& Session s = session.get();
&&&&&&& if ( s == null )
&&&&&&&&&&& s = sessionFactory.openSession();
&&&&&&&&&&& session.set( s );
&&&&&&& return(s);
&&& public static void closeSession() throws HibernateException
&&&&&&& Session s = session.get();
&&&&&&& if ( s != null )
&&&&&&&&&&& s.close();
&&&&&&& session.set( null );
接下来,我们将事务放在service中。看代码:
public class TestService {
&&& public void save(User user){
&&&&&&& SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory
&&&&&&& Session session = sessionFactory.getCurrentSession();//getCurrentSession
&&&&&&& session.beginTransaction();//事务开始
&&&&&&& UserDao userDao = new UserDao();
&&&&&&& userDao.saveUser(user);
&&&&&&& LogDao logDao = new LogDao();
&&&&&&& Log log = new Log();
&&&&&&& log.setContent(&插入一个用户&);
&&&&&&& logDao.saveLog(log);
&&&&&&& session.getTransaction().commit();//事务提交
public class LogDao {
&&& public void saveLog(Log log) throws RuntimeException{
&&&&&&& SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory
&&&&&&& Session session = sessionFactory.getCurrentSession(); //getCurrentSession
&&&&&&& session.save(log);
&&&&&&& throw new RuntimeException();
public class UserDao {
&&& public void saveUser(User user){
&&&&&&& SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory
&&&&&&& Session session = sessionFactory.getCurrentSession();//getCurrentSession
&&&&&&& session.save(user);
通过getCurrentSession()可以获得当前线程的session对象,通过它来进行共享session。这样事务就从service开始,然后再service结束。
getCurrentSession()与openSession()区别
getCurrentSession创建的session会和绑定到当前线程,而openSession不会。
getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭
采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
&property name=&hibernate.current_session_context_class&&thread&/property&
* 如果使用的是全局事务(jta事务)
&property name=&hibernate.current_session_context_class&&jta&/property&
getCurrentSession()与openSession()关联
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
上一页: &&&&&下一页:相关内容hibernate(10)
& & & & 这几天在学习hibernate的核心开发接口,了解到hibernate的session有两种获取方式,一种是通过Session session = sessionFactory.openSession()来获取,另外一种是通过Session session = sessionFactory.getCurrentSession()方法来获取,那么这两种方法有啥区别呢?
& & & & &首先OpenSession()是永远打开一个新的session,这个可以通过下面的方法来证明: & & & &
public void test() {
Student s =
new Student();
StudentPK pk =
new StudentPK();
s.setPk(pk);
s.setAge(23);
s.setClasses(1);
pk.setId(1);
pk.setName(&moluo&);
Session session = sf.openSession();
Session session1 = sf.openSession();
session.beginTransaction();
session.save(s);
System.out.println(session == session1);
//输出结果为
session.getTransaction().commit();
session.close();
session1.close();
}输出结果为false,显然这俩session不是同一个session,所以openSession()每次都是new一个新的session。 & & & &
& & & & &其次,OpenSession()打开一个session以后必须显式的去关闭(session.close())。
& & & & &再来看看getCurrentSession(),它是从上下文里找,如果有session,它就使用原来的session,如果没有它就new一个session。怎么证明呢?来看看下面这个例子:
public void test() {
Student s =
new Student();
StudentPK pk =
new StudentPK();
s.setPk(pk);
s.setAge(23);
s.setClasses(1);
pk.setId(1);
pk.setName(&moluo&);
Session session = sf.getCurrentSession();
Session session1 = sf.getCurrentSession();
session.beginTransaction();
session.save(s);
System.out.println(session == session1);
//输出结果为
session.getTransaction().commit();
//session.close();
//session1.close();
}输出结果为true,显然这俩session是同一个session,否则输出结果就是false了,也就是说当上下文如果存在一个session,它就使用原来的session。在事物没有提交或者回滚之前,无论我们拿多少次session,它们都是同一个session,但如果提交或者回滚了,再拿就是新的session了。
& & & & &另外,getCurrentSession()不需要我们显式的去关闭,因为当事物提交(session.getTransaction().commit())或者回滚之后,会自动的帮我们去关闭session。如果我们显式的去关闭session,就有可能会出现问题,所以不要去多此一举。
& & & & & 既然提到了他俩都可以获取session,那么他俩获取到的session是否为同一个session呢?再看下面的例子:
public void test() {
Student s =
new Student();
StudentPK pk =
new StudentPK();
s.setPk(pk);
s.setAge(23);
s.setClasses(1);
pk.setId(1);
pk.setName(&moluo&);
Session session = sf.openSession();
Session session1 = sf.getCurrentSession();
session.beginTransaction();
session.save(s);
System.out.println(session == session1);
//输出结果为
session.getTransaction().commit();
//session.close();
}& & & & 输出结果为false,证明他俩不是同一个session,有些朋友就有可能会有疑问了,session1是通过getCurrentSession()得到的,而getCurrentSession()不是通过上下文获取session吗?上下文不是openSession(),不是已经有了一个session了吗?实际上session是一个接口,通过这俩方式得到的session的具体实现方式是不一样的,所以输出结果为false。
& & & & &讲到getCurrentSession()会从上下文里获取session,那么上下文的配置在哪呢?实际上在sf = new AnnotationConfiguration().configure().buildSessionFactory();这步就已经调用配置文件hibernate.cfg.xml了,如果配置文件不是这个默认名,而是hibernate.xml,那么就必须改成:
sf = new AnnotationConfiguration().configure(“hibernate.xml”).buildSessionFactory();也就是说在configure()方法就调用了配置文件。
& & & & & 回归正题:上下文配置在配置文件的:
&property name=&current_session_context_class&&thread&/property&& & & & &这里一共有4个可选的参数,分别是:jta,thread,custom,managed。前两者比较常用,后两者很少用到。
& & & & &thread使用connection,用于单数据库连接事物管理,而jta(java transaction api)运行时需要application server提供支持,它主要用于多数据库,分布式事物管理,用于界定事物边界。
& & & & 另外,getCurrentSession()创建的session会绑定到当前线程中,而openSession()不会绑定。
& & & & &最后还有一点就是:openSession()可以在不开启事物的情况下执行,而getCurrentSession()不行。(这个是在网上看来的,未经佐证!)
尊重版权,转载请不要删除下方二维码并注明本文链接
& & & & & & & & & & & & & & & & &欢迎关注行者摩罗微信公众号(xingzhemoluo),共同交流编程经验,扫描下方二维码即可;
& & & & & & & & & & & & & & & & & & & & & & & & & & & &&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:20736次
排名:千里之外
原创:41篇}

我要回帖

更多关于 hibernate中的session 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信