Hibernate的openSession和getCurrentSession区别
来源:互联网 发布:java方法定义 编辑:程序博客网 时间:2024/04/30 06:03
原文链接:http://blog.csdn.net/xiao__gui/article/details/7695698
很多资料从理论上解释hibernate的openSession和getCurrentSession的区别,本人写了几个程序来理解它们的区别,在这里和大家分享一下。
简单来说,openSession是打开一个新的session,而getCurrentSession则是获取当前线程里的session,如果没有才打开新的。
hibernate可以通过session来控制事务,有了getCurrentSession方法意味着可以将对数据库的操作代码放到不同的地方(不同类的方法中),这样事务控制起来极为方便。在实际开发中,业务逻辑和数据库操作一般会分层,也就是Service层和DAO层。DAO只是单纯的操作数据库,不包含业务逻辑;而Service中的一个业务逻辑可能包含多个数据库操作。
例如:业务逻辑要求向数据库中的用户表增加一个用户,同时向日志表中加入一条日志,而这需要调用DAO的两个方法(UserDao的saveUser和LogDao的saveLog)。这显然是一个事务,也就是如果一个操作出现了问题,就要回滚到初始的状态。那么如何在Service层控制事务呢,本文就以此例的代码说明。
Hibernate文档中有个辅助类HibernateUtil,用于获取SessionFactory:
package com.xxg; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; 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(); } catch (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 sessionFactory; } }
创建用户表T_user(id,username)和日志表T_log(id,content),以及它们对应的实体类User、Log及映射文件,这里就不一一贴出代码。
1、首先使用openSession来测试一下:
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 } }
以上两个类是数据库操作Dao层。
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); } }
以上是service代码,分别调用两个Dao的方法来完成业务逻辑。
public class Test { public static void main(String[] args) { User user = new User(); user.setUsername("xxg"); TestService testService = new TestService(); testService.save(user); } }
最后写一个main方法调用service。
运行,结果如愿。但是,很明显可以看出来,以上代码的service根本没有事务控制。
在LogDao的saveLog方法最后加上一句:
throw new RuntimeException();
public class LogDao { public void saveLog(Log log) throws RuntimeException{ SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); //获取SessionFactory Session session = sessionFactory.openSession();// openSession session.beginTransaction(); //开始事务 session.save(log); session.getTransaction().commit(); //事务提交 session.close(); //关闭session throw new RuntimeException(); } }
再运行一下,发现数据同样还会插入到数据库中。实际上如果在运行期间事务中出现异常,hibernate就会rollback回滚,但是在这里没办法回滚。同样如果插入log出现异常,user表也同样能正常插入数据。
也就是:此时事务的边界在Dao的方法内,而不是在Service方法内。
2.改成getCurrentSession
此时要将事务的边界放到Service中,所以在service中写开始和结束事务的语句,DAO中则不写。
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); } }
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();//事务提交 } }
以上代码就可以看出来,事务的边界已然在Service中了,因为在这里使用的是getCurrentSession方法,所以在运行过程中service中session和Dao中的session是同一个对象,是“==”的。这样就可以在servie中开始和提交事务。
运行一下,发现回滚了,结果是user表以及log表都没有插入数据。把throw new RuntimeException();去掉再运行,则正常插入。这才是想要的结果。
以上的代码不全,如果想理解这两个方法的区别,不妨动手做做实验。
- hibernate 的openSession和getCurrentSession的区别
- Hibernate openSession() 和 getCurrentSession的区别
- Hibernate openSession() 和 getCurrentSession的区别
- Hibernate中openSession 和 getCurrentSession 的区别
- Hibernate 中 openSession()和getCurrentSession() 的区别
- Hibernate openSession()和getCurrentSession()的区别
- Hibernate openSession() 和 getCurrentSession的区别
- hibernate之openSession()和getCurrentSession()的区别
- Hibernate openSession() 和 getCurrentSession的区别
- hibernate: openSession() 和getCurrentSession()的区别
- Hibernate openSession() 和 getCurrentSession的区别 .
- Hibernate的openSession和getCurrentSession区别
- hibernate中 openSession和getCurrentSession的区别
- Hibernate openSession() 和 getCurrentSession的区别
- 【Hibernate】OpenSession和getCurrentSession的区别
- Hibernate openSession() 和 getCurrentSession的区别
- Hibernate getCurrentSession()和openSession()的区别
- Hibernate openSession() 和 getCurrentSession的区别
- 字符型char和整型int之间的关系
- 【Data Structures】 1. Collection
- 日期字符串互换
- 【存档】CSDN-markdown编辑器的markdown语法
- 10302
- Hibernate的openSession和getCurrentSession区别
- 插入排序算法
- Codeforces 344D - Alternating Current
- vr相关文章第一弹,屏幕分辨率和屏幕ppi的区别
- 程序员必备的七大面向对象设计原则(三)
- 转移字符中的双引号,单引号和反斜杠
- Linux进程间通信 -- 信号量
- while(0),while(1),while(表达式)
- HDU - 1215 七夕节