在上一篇《初識Hibernate》中簡單介紹了在Hibernate如何加載對象和持久化對象,以及Hibernate中對象實例狀態。本文將繼續介紹Hibernate簡單的增刪改查方法和對對象實例狀態的理解(查詢方法暫不說起)。
@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語句。
這裏的查詢準確來講應該稱爲對象加載。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() ;
更新操做並無使用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緩存中的對象與數據庫中相應的記錄不一致,就會同步數據庫。
@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緩存中刪除。
同時包含了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緩存。
Hibernate中的對象有3中狀態,瞬時對象(TransientObjects)、持久化對象(PersistentObjects)和離線對象(DetachedObjects也叫作脫管對象)。
Java對象在Hibernate持久化層的狀態:
@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=?