Hibernate的openSession和getCurrentSession区别
原文鏈接: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();
再運行一下,發現數據同樣還會插入到數據庫中。實際上如果在運行期間事務中出現異常,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区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle丢失管理员密码的解决方法
- 下一篇: ConcurrentHashMap的实现