1 對象狀態與一級緩存sql
l hibernate 規定三種狀態:瞬時態、持久態、脫管態數據庫
l 狀態api
瞬時態:transient,session沒有緩存對象,數據庫也沒有對應記錄。緩存
OID特色:沒有值session
持久態:persistent,session緩存對象,數據庫最終會有記錄。(事務沒有提交)優化
OID特色:有值spa
脫管態:detached,session沒有緩存對象,數據庫有記錄。hibernate
OID特色:有值代理
l 得到:通常都只直接建立(new)對象
l 瞬時態 轉換 持久態
通常操做:save方法、saveOrUpdate
l 瞬時態 轉換 脫管態
通常操做:經過setId方法設置數據
例如:
User user = new User(); //瞬時態
user.setUid(1); //脫管態
l 得到:
查詢操做:get、loat、createQuery、createCriteria 等 得到都是持久態【】
執行save以後持久態
執行update以後持久態
l 持久態 轉換 瞬時態
官方規定執行delete() --民間:刪除態
l 持久態 轉換 脫管態
session沒有記錄
session.close () 關閉
session.clear() 清除全部
session.evict(obj) 清除指定的PO對象
l 得到:
建立、並設置OID的
經過api得到
l 脫管態 轉換 瞬時態
手動去除OID,設置成默認值
l 脫管態 轉換 持久態
通常操做:update()、saveOrUpdate
@Test public void demo01(){ User user = new User(); //瞬時態 user.setUsername("jack"); user.setPassword("1234"); //瞬時態(與oid沒有關係)
Session session = factory.openSession(); session.beginTransaction();
session.save(user); //持久態 //---- 持久態就應該有持久態的行爲(特性)
// user.setUsername("rose"); //持久態對象 被修改後,hibernate將自動生成update語句 // session.flush();
session.getTransaction().commit(); session.close();
System.out.println(user); //脫管態 } |
l 一級緩存:又稱爲session級別的緩存。當得到一次會話(session),hibernate在session中建立多個集合(map),用於存放操做數據(PO對象),爲程序優化服務,若是以後須要相應的數據,hibernate優先從session緩存中獲取,若是有就使用;若是沒有再查詢數據庫。當session關閉時,一級緩存銷燬。
@Test public void demo02(){ //證實一級緩存 Session session = factory.openSession(); session.beginTransaction();
//1 查詢 id = 1 User user = (User) session.get(User.class, 1); System.out.println(user); //2 再查詢 -- 不執行select語句,將從一級緩存得到 User user2 = (User) session.get(User.class, 1); System.out.println(user2);
session.getTransaction().commit(); session.close(); } |
@Test public void demo03(){ //清除緩存 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
//清除 //session.clear(); session.evict(user);
// 一級緩存沒有緩存對象,從數據庫直接查詢 User user2 = (User) session.get(User.class, 1); //--select System.out.println(user2);
session.getTransaction().commit(); session.close(); } |
l 快照:與一級緩存同樣的存放位置,對一級緩存數據備份。保證數據庫的數據與 一級緩存的數據必須一致。若是一級緩存修改了,在執行commit提交時,將自動刷新一級緩存,執行update語句,將一級緩存的數據更新到數據庫。
l refresh 保證 一級緩存的數據 與 數據庫的數據 保持一致。將執行select語句查詢數據庫,將一級緩存中的數據覆蓋掉。只要執行refresh都將執行select語句。
@Test public void demo04(){ //刷新 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
session.refresh(user);
session.getTransaction().commit(); session.close(); } |
@Test public void demo05(){ //快照 Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 1); //--select System.out.println(user);
//修改持久態對象內容(一級緩存內容)--默認在commit時,將觸發update語句。 user.setUsername("rose2");
session.getTransaction().commit(); session.close(); } |
l 問題:一級緩存何時刷新?(瞭解)
默認狀況提交(commit())刷新。
@Test public void demo06(){ //設置刷新時機 Session session = factory.openSession(); session.beginTransaction();
//1 設置 session.setFlushMode(FlushMode.MANUAL);
User user = (User) session.get(User.class, 1); user.setUsername("rose4");
//1 查詢全部 -- AUTO , 查詢以前先更新,保存一級緩存和數據庫同樣的 //List<User> allUser = session.createQuery("from User").list();
//2手動刷新 --MANUAL 將執行update,注意:一級緩存必須修改後的 session.flush();
// 若是MANUAL 在執行commit 不進行update session.getTransaction().commit(); session.close(); } |
l save方法:瞬時態 轉換 持久態 ,會初始化OID
1.執行save方法,當即觸發insert語句,從數據庫得到主鍵的值(OID值)
2.執行save方法前,設置OID將忽略。
3.若是執行查詢,session緩存移除了,在執行save方法,將執行insert
@Test public void demo01(){ User user = new User(); user.setUid(100); user.setUsername("jack"); user.setPassword("1234");
Session session = factory.openSession(); session.beginTransaction();
session.save(user);
session.getTransaction().commit(); session.close(); } |
@Test public void demo03(){ //代理 assigned User user = new User(); //user.setUid(100); user.setUsername("jack"); user.setPassword("1234");
Session session = factory.openSession(); session.beginTransaction();
session.save(user);
session.getTransaction().commit(); session.close(); } |
l 注意:持久態對象不能修改OID的值
@Test public void demo04(){
Session session = factory.openSession(); session.beginTransaction();
User user = (User) session.get(User.class, 100); user.setUid(101);
session.save(user);
session.getTransaction().commit(); session.close(); } |
l persist方法:瞬時態 轉換 持久態 ,不會當即初始化OID
注意: persist方法不會當即獲得ID,因此執行sql語句的時機要靠後.
l update:脫管態 轉換 持久態
若是OID在數據存放的,將執行update語句
若是OID不存在將拋異常
@Test public void demo01(){ //天然 assigned User user = new User(); user.setUid(101); user.setUsername("jack1"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
session.update(user);
session.getTransaction().commit(); session.close(); } |
l 注意1:若是數據沒有修改,執行save方法,將觸發update語句。
查詢速度 比 更新速度快
經過<class select-before-update> 來設置更新前先查詢,若是沒有改變就不更新。
總結:
update 以後對象 持久態
@Test public void demo03(){ // merge 合併 User user = new User(); user.setUid(1); user.setUsername("jack3"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
// 1 oid =1 持久態對象 User user2 = (User) session.get(User.class, 1);
// session.update(user); session.merge(user);
session.getTransaction().commit(); session.close(); } |
l 代理主鍵:
判斷是否有OID
若是沒有OID,將執行insert語句
若是有OID,將執行update語句。
@Test public void demo02(){ // 代理 native User user = new User(); // user.setUid(2); user.setUsername("jack2"); user.setPassword("12345");
Session session = factory.openSession(); session.beginTransaction();
session.saveOrUpdate(user);
session.getTransaction().commit(); session.close(); } |
l 天然主鍵:
先執行select語句,查詢是否存放
若是不存在,將執行insert
若是存在,將執行update
@Test public void demo02(){ // 天然 assigned User user = new User(); user.setUid(2); user.setUsername("jack2333"); user.setPassword("12345333");
Session session = factory.openSession(); session.beginTransaction();
session.saveOrUpdate(user);
session.getTransaction().commit(); session.close(); } |
l 注意1:native下,默認OID是否存在,使用默認值。例如:Integer 默認null
經過<id unsaved-value="1"> 修改使用默認值,若是設置1進行insert語句。此內容提供hibernate使用的,錄入到數據庫後,採用自動增加。
總結:
PO對象狀態:瞬時態、持久態、脫管態