Hibernate之CRUD與實例狀態

在上一篇《初識Hibernate》中簡單介紹了在Hibernate如何加載對象和持久化對象,以及Hibernate中對象實例狀態。本文將繼續介紹Hibernate簡單的增刪改查方法和對對象實例狀態的理解(查詢方法暫不說起)。

1、HibernateのCRUD操做

1.1 HibernateのCreate

@Test
    public void testCreate() {
        Session session = HibernateUtils.getSession();
        User user = new User();
        user.setId(3);
        user.setUserName("Sandy");
        user.setPassWord("aaa");
        session.save(user);
    }

注意:Hibernate事務默認是關閉的,執行後不會報錯,可是數據並無成功插入數據庫。java

控制檯輸出:Schema update complete數據庫

解決辦法:手動設置事務提交緩存

@Test
    public void testCreate() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        User user = new User();
        user.setId(3);
        user.setUserName("Sandy");
        user.setPassWord("aaa");
        session.save(user);
        tx.commit();
    }

控制檯輸出:Hibernate: insert into tbl_user (username, password, id) values (?, ?, ?)session

save()方法把一個臨時對象加入到Session緩存中,並持久化該臨時對象,計劃執行一個insert語句。

1.2 HibernateのRead

這裏的查詢準確來講應該稱爲對象加載app

Hibernate中 session.get()方式獲取被稱爲對象加載,只能從數據庫中加載出惟一一條記錄。查詢多條數據Hibernate另提供了API。
@Test
    public void testRead() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        User user = (User)session.get(User.class, 3);
        System.out.println(user);
        tx.commit();
    }

控制檯輸出:Hibernate: select user0_.id as id1_8_0_, user0_.username as username2_8_0_, user0_.password as password3_8_0_ from tbl_user user0_ where user0_.id=?
User{id=3, userName='Sandy', passWord='aaa'}spa

get()load() 試圖從數據庫加載一個實體對象時,Session先判斷對象是否存在,若是存在就不到數據庫中檢索。返回的對象都位於Session緩存中,接下來修改了持久化對象的屬性後,當Session清理緩存時,會根據持久化對象的屬性變化來同步更新數據庫。

區別:代理

​ (1)當數據庫中不存在與OID對應的記錄時,load()方法拋出ObjectNotFoundException異常,而get()方法返回null.code

​ (2)二者採用不一樣的檢索策略。對象

​ 默認狀況下,load()方法採用延遲檢索策略(Hibernate不會執行select語句,僅返回實體類的代理類實例,佔用內存不多);而get()採用當即檢索策略(Hibernate會當即執行select語句)。事務

使用場合:

​ (1)若是加載一個對象的目的是爲了訪問它的各個屬性,能夠用get();

​ (2)若是加載一個對象的目的是爲了刪除它,或者創建與別的對象的關聯關係,能夠用load() ;

1.3 HibernateのUpdate

更新操做並無使用 session.update()方法,直接 tx.commit()便可以成功更新數據。 session.upate()方法另有做用。
@Test
    public void testUpdate() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        User user = (User)session.get(User.class, 3);
        user.setUserName("Bob");
        user.setPassWord("123");
        // 髒數據(Dirty Data)
        // 過期數據檢測(前提是該對象是持久態)
        tx.commit();
    }

控制檯輸出:Hibernate: select user0_.id as id1_8_0_, user0_.username as username2_8_0_, user0_.password as password3_8_0_ from tbl_user user0_ where user0_.id=?
Hibernate: update tbl_user set username=?, password=? where id=?

Session在清理緩存的時候會自動進行 髒檢查(dirty-check),若是發現Session緩存中的對象與數據庫中相應的記錄不一致,就會同步數據庫。

1.4 HibernateのDelete

@Test
    public void testDelete() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        User user = (User)session.get(User.class, 3);
        user.setUserName("Bob");
        user.setPassWord("123");
        session.delete(user);
        tx.commit();
    }

控制檯輸出:Hibernate: select user0_.id as id1_8_0_, user0_.username as username2_8_0_, user0_.password as password3_8_0_ from tbl_user user0_ where user0_.id=?
Hibernate: delete from tbl_user where id=?

計劃執行一個delete語句,把對象從Session緩存中刪除。

1.5 saveOrUpdate

同時包含了save()和update()方法的功能。若是傳入的是臨時對象,就調用save()方法;若是傳入的是遊離對象,就調用update()方法若是傳入的是持久化對象,就直接返回。
@Test
    public void testSaveOrUpdate() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        User user = new User();
        user.setId(5);
        user.setUserName("Sandy");
        user.setPassWord("123");
        session.saveOrUpdate(user);

        User user2 = (User)session.get(User.class, 1);
        user2.setUserName("Andy");
        user2.setPassWord("apple");
        session.saveOrUpdate(user2);
        tx.commit();
        session.close();
    }

控制檯輸出:Hibernate: select user_.id, user_.username as username2_8_, user_.password as password3_8_ from tbl_user user_ where user_.id=?
Hibernate: select user0_.id as id1_8_0_, user0_.username as username2_8_0_, user0_.password as password3_8_0_ from tbl_user user0_ where user0_.id=?
Hibernate: insert into tbl_user (username, password, id) values (?, ?, ?)
Hibernate: update tbl_user set username=?, password=? where id=?

update()方法把遊離對象加入當前Session緩存中,計劃執行update語句。當update()方法關聯一個遊離對象時,若是session緩存中已經有一個同類型且ID相同的持久化對象,那麼update()方法會拋出NonUniqueException異常。當update()方法關聯一個持久化對象時,該方法不起做用。

close():清空session緩存。

2、Hibernateの實例狀態

Hibernate中的對象有3中狀態,瞬時對象(TransientObjects)、持久化對象(PersistentObjects)和離線對象(DetachedObjects也叫作脫管對象)。

Hibernate對象狀態轉換圖

Java對象在Hibernate持久化層的狀態:

  1. 瞬時(transient)狀態:剛用new語句建立,尚未被持久化,而且不處於session緩存中(處於臨時狀態的對象成爲臨時對象)。
  2. 持久化(Persistent)狀態:已經被持久化,而且加入到session緩存中。處於持久化狀態的對象稱爲持久化對象。
  3. 遊離(Detached)狀態:已經被持久化,但再也不處於session緩存中。處於遊離狀態的對象稱爲遊離對象。
  4. 刪除狀態:再也不處於session緩存中,而且session已經計劃將其從數據庫中刪除。
@Test
    public void testState() {
        Session session = HibernateUtils.getSession();
        Transaction tx = session.beginTransaction();
        // 持久態對象
        // 1.在數據庫中有惟一一條記錄關聯 2.必須跟一個session關聯(必須歸入Hibernate容器)
        User user = (User)session.get(User.class, 1);

        // 臨時態
        // User user = new User();

        user.setUserName("Fancy");
        user.setPassWord("abc");

        // 髒數據(Dirty Data)過期數據檢測(前提是該對象是持久態)
        tx.commit();
        // 關閉session
        session.close();

        // 遊離態(Detached)
        // 1.在數據庫中有惟一一條記錄對應 2.當前user沒有跟Hibernate的session關聯(曾經跟Hibernate關聯,如今沒有)
        // 沒法進行髒數據檢測
        System.out.println(user);

        //把遊離態對象變爲持久態(再次歸入Hibernate容器管理,再跟一個session關聯起來)
        Session session2 =HibernateUtils.getSession();
        Transaction tx2 = session2.beginTransaction();
        user.setUserName("Kathy");
        user.setPassWord("good");

        //把遊離態對象同一個session關聯,將對象狀態變爲持久態
        session2.update(user);
        tx2.commit();
    }
}

控制檯輸出:Hibernate: select user0_.id as id1_8_0_, user0_.username as username2_8_0_, user0_.password as password3_8_0_ from tbl_user user0_ where user0_.id=?User{id=1, userName='Fancy', passWord='abc'}Hibernate: update tbl_user set username=?, password=? where id=?

相關文章
相關標籤/搜索