日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate的openSession和getCurrentSession区别

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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();

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区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。