Java Hibernate 之 Session 狀態
Session介面是Hibernate向程式提供操縱資料庫的最主要介面,是單執行緒物件,它提供了基本的儲存、更新、刪除和查詢方法。它有一個快取,儲存了持久化物件,當清理快取時,按照這些持久化物件同步更新資料庫。
注意:session的某些方法(persist,load)不會立即把改動寫入資料庫,而是快取到session的一級快取中,除非顯示呼叫flush,或者關閉session時才會更新到資料庫
- 臨時狀態(Transient):沒與session關聯
- 持久化狀態(Persistent):與session關聯,沒close
- 遊離狀態(Detached):當session.close後
Session的方法詳解
1.儲存
save:立即插入資料庫,並且返回主鍵
persist:不立即(延遲)插入資料庫,無返回值
2.獲取
load:載入物件後,對物件的改動不會立即重新整理到db,必須flush到db
ex: User user=session.load(User.class,2);
user.setName(‘gt’);
user.flush(); (延遲載入)
get:載入物件後,對物件的改動立即重新整理到db
3.更新
update:持久化物件,更新
saveOrUpdate:包含save()和update()功能,如果傳入的引數是臨時物件(沒有儲存過)就呼叫save()方法;如果傳入的引數是遊離物件,就呼叫update()方法
merge:不會持久化物件,只會把託管物件的修改更新到db
4.刪除
delete:從資料庫中刪除與JAVA物件對應的記錄
5.清理
flush:把快取同步到db
clear:清除session的快取大小(更新批量時,應考慮)
三種狀態的轉換關係
下面通過例項講解:
實體:
package cn.itcast.h_session_method; public class User { private Integer id; private String name; private byte[] data = new byte[1024 * 1024 * 5]; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
對映檔案:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.itcast.h_session_method"> <!-- lazy屬性:預設為true,預設可以懶載入。 --> <class name="User" table="user" lazy="true"> <id name="id"> <generator class="native"></generator> </id> <property name="name"/> </class> </hibernate-mapping>
配置檔案:hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!--資料庫連線設定 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="connection.url"> jdbc:mysql://localhost:3306/mytest </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- 方言 --> <property name="dialect"> org.hibernate.dialect.MySQL5Dialect </property> <!-- 控制檯顯示SQL --> <property name="show_sql">true</property> <!-- 自動更新表結構 --> <property name="hbm2ddl.auto">update</property> <mapping resource="cn/itcast/h_session_method/User.hbm.xml" /> </session-factory> </hibernate-configuration>
測試檔案
package cn.itcast.h_session_method; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.junit.Test; import com.java1234.util.HibernateSessionFactory; public class App { private static SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory(); // save():把臨時狀態變為持久化狀態(交給Sessioin管理) // 會生成:insert into ... @Test public void testSave() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = new User(); // 臨時狀態 user.setName("test"); session.save(user); // 變為了持久化狀態 // -------------------------------------------- session.getTransaction().commit(); session.close(); user.setName("李四"); // 遊離狀態 System.out.println(user.getName()); // 遊離狀態 } // update():把遊離狀態變為持久化狀態 // 會生成:update ... // 在更新時,物件不存在就報錯 @Test public void testUpdate() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = (User) session.get(User.class, 1); System.out.println(user.getName()); // 持久化狀態 // session.clear(); // 清除Session中所有的物件 session.evict(user); // 清除Session中一個指定的物件 user.setName("newname3"); session.update(user); System.out.println("----"); // session.flush(); // 刷出到資料庫 // -------------------------------------------- session.getTransaction().commit(); // session.close(); } // saveOrUpdate():把臨時或遊離狀態轉為持久化狀態 // 會生成:insert into 或 update ... // 在更新時,物件不存在就報錯 // 本方法是根據id判斷物件是什麼狀態的:如果id為原始值(物件的是null,原始型別數字是0)就是臨時狀態,如果不是原始值就是遊離狀態。 @Test public void testSaveOrUpdate() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = new User(); user.setId(3); // 自己生成一個遊離狀態物件 user.setName("newName"); session.saveOrUpdate(user); // -------------------------------------------- session.getTransaction().commit(); session.close(); } // delete():把持久化或遊離轉為刪除狀態 // 會生成:delete ... // 如果刪除的物件不存在,就會拋異常 @Test public void testDelete() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- // User user = (User) session.get(User.class, 2); // 持久化 User user = new User(); user.setId(300); session.delete(user); session.flush(); System.out.println("---"); // -------------------------------------------- session.getTransaction().commit(); session.close(); } // get():獲取資料,是持久化狀態 // 會生成:select ... where id=? // 會馬上執行sql語句 // 如果資料不存在,就返回null @Test public void testGet() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = (User) session.get(User.class, 5); // 持久化 System.out.println(user.getClass()); // System.out.println("---"); // System.out.println(user.getName()); // -------------------------------------------- session.getTransaction().commit(); session.close(); } // load():獲取資料,是持久化狀態 // 會生成:select ... where id=? // load()後返回的是一個代理物件,要求類不能是final的,否則不能生成子類代理,就不能使用懶載入功能了。 // 讓懶載入失效的方式:一、把實體寫成final的;二、在hbm.xml中寫<class ... lazy="false"> // 不會馬上執行sql語句,而是在第1次使用非id或class屬性時執行sql。 // 如果資料不存在,就拋異常:ObjectNotFoundException @Test public void testLoad() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = (User) session.load(User.class, 5); System.out.println(user.getClass()); System.out.println("---"); System.out.println(user.getId()); System.out.println(user.getName()); // System.out.println(user.getName()); // -------------------------------------------- session.getTransaction().commit(); session.close(); } // 操作大量資料,要防止Session中物件過多而記憶體溢位 @Test public void testBatchSave() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- for (int i = 0; i < 30; i++) { User user = new User(); user.setName("測試"); session.save(user); if (i % 10 == 0) { session.flush(); // 先刷出 session.clear(); // 再清空 } } // -------------------------------------------- session.getTransaction().commit(); session.close(); } @Test public void test2() throws Exception { Session session = sessionFactory.openSession(); session.beginTransaction(); // -------------------------------------------- User user = (User) session.get(User.class, 5); // 持久化 System.out.println(user.getName()); // session.clear(); // user = (User) session.get(User.class, 5); // 持久化 session.refresh(user); // 重新整理Session快取中物件的狀態,即重新select一下 System.out.println(user.getName()); // -------------------------------------------- session.getTransaction().commit(); session.close(); } }
對於剛建立的一個物件,如果session中和資料庫中都不存在該物件,那麼該物件就是臨時物件(Transient)
臨時物件呼叫save方法,或者遊離物件呼叫update方法可以使該物件變成持久化物件,如果物件是持久化物件時,那麼對該物件的任何修改,都會在提交事務時才會與之進行比較,如果不同,則傳送一條update語句,否則就不會傳送語句
遊離物件就是,資料庫存在該物件,但是該物件又沒有被session所託管
相關文章
- Hibernate物件狀態物件
- SSH框架之-hibernate 三種狀態的轉換框架
- 【Oracle】-【v$session】v$session的SNIPED狀態OracleSession
- Hibernate 持久化物件的狀態持久化物件
- Hibernate持久化物件的狀態持久化物件
- Java設計模式之狀態模式Java設計模式
- 什麼時候用有狀態session bean,什麼時候用無狀態session bean (轉)SessionBean
- 深入理解hibernate的三種狀態
- 折騰Java設計模式之狀態模式Java設計模式
- JAVA設計模式之 狀態模式【State Pattern】Java設計模式
- 菜鳥學SSH(九)——Hibernate——Session之save()方法Session
- 【hibernate】Session快取Session快取
- hibernate中po物件的三種狀態分析物件
- Java Hibernate 之 CRUD 操作Java
- session的狀態什麼時候是snipedSession
- Hibernate的三種狀態及物件生命週期物件
- 如何管理hibernate 的session?Session
- Hibernate的session問題Session
- No Hibernate Session bound to threadSessionthread
- MTS方式連線V$SESSION中的SERVER狀態SessionServer
- hibernate(二)一級快取和三種狀態解析快取
- 菜鳥學SSH(八)——Hibernate物件的三種狀態物件
- Flutter 狀態管理之BLoCFlutterBloC
- react之redux狀態管理ReactRedux
- cookie儲存使用者狀態 無session系統CookieSession
- hibernate中的no session問題Session
- HIBERNATE的SESSION和事務Session
- Java併發程式設計序列之執行緒狀態Java程式設計執行緒
- hibernate的session.connection被session.dowork()替代Session
- 【演算法】狀態之美,TCP/IP狀態轉換探索演算法TCP
- Java執行緒的狀態Java執行緒
- java Thread的狀態分析Javathread
- Java序列化的狀態Java
- java狀態模式例項解析Java模式
- SESSION處於KILLED狀態下如何找出對應的程式Session
- 爬蟲如何利用session方法保持登陸狀態(selenium)爬蟲Session
- Toad中發現blocking session, 狀態為inactiveBloCSession
- PyQt5 之狀態列QT