在Hibernate中java對象的狀態:
1、臨時狀態(Transient):
與數據庫沒有對應,跟Session沒有關聯
一般是新new出的對象
2、持久化狀態(Persist):
對象再Session的管理之中,最終會有對應的數據記錄
特點:
a、有OID(唯一標示)
b、對對象的修改會同步到數據庫中
3、遊離狀態(Detached):
數據庫中有對應記錄,但對象不再Session管理之中
修改了此狀態對象時,數據庫不會變化
4、刪除狀態(Removed):
執行了delete()後的對象
Session中的方法:
一、操作實體對象的方法
save()
update()
saveOrUpdate()
delete()
二、操作緩存的方法
clear()
evict()
flush() 馬上執行數據庫操作,默認是在事務提交的時候才執行,但是save()和get()的時候會馬上執行
三、查詢實體對象的方法
get()
load()
createQuery()
createCriteria()
下面演示的是save()方法,它能把對象的臨時狀態變成持久化狀態。第9行新建一個User對象,此時對象時臨時狀態,第9行調用session的save()方法,將對象變成了持久化狀態,交給Session管理,但此時並不馬上執行insert語句,而是在事務提交,session關閉的時候纔會執行insert語句。第13行設置了對象的名字爲“李四”,第16行提交事務,第17行關閉session,此時就會執行insert語句,所以數據庫中新插入的數據其name屬性爲李四,而不是一開始的test。只要對象屬於持久化狀態,對對象屬性的操作,都會作用於數據庫中。
//save():把臨時狀態變爲持久化狀態(交給Session管理)
@Test
public void testSave(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
//構建對象
User user = new User(); //臨時狀態
user.setName("test");
session.save(user); //變成持久化狀態
user.setName("李四");
//-----------------------------------------------
session.getTransaction().commit();
session.close();
System.out.println(user.getName());
}
下面演示的是update()方法,它能把遊離狀態的對象變成持久化狀態。第8行通過id獲取對象,得到的對象爲持久化狀態。第11行爲對象屬性設置新值,第12行調用session的flush()方法,此方法是將session中的數據刷出到數據庫,此時會馬上執行update語句更新數據庫,第13行清空了session中的所有對象,此時之前的user對象變成了遊離的狀態,如果有清除session中的指定對象,可以使用evict方法。
//update():把遊離狀態變爲持久化狀態
@Test
public void testUpdate(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 9);
System.out.println(user.getName()); //持久化狀態
user.setName("newname");
session.flush(); //刷出到數據庫
session.clear(); //變爲遊離狀態,清除session中所有的對象
//session.evict(user); //清除session中一個指定的對象
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是saveOrUpdate()方法,它能把臨時或遊離狀態的對象轉換爲持久化狀態。
//saveOrUpdate():把臨時或遊離狀態轉爲持久化狀態
//在更新的時候,如果對象不存在就報錯
//本方法是根據id判斷對象是什麼狀態的:如果id爲原始值(對象的是null,原始類型的數字是0)
//就是臨時狀態,如果不是原始值就是遊離狀態
@Test
public void testSaveOrUpdate(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = new User();
user.setId(9); //自己生成一個遊離狀態對象
user.setName("白子畫");
session.saveOrUpdate(user);
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是delete()方法,它能把持久化或遊離狀態的對象轉換爲刪除狀態。
//delete():把持久化或遊離狀態轉換爲刪除狀態
//如果刪除的對象不存在,就會拋異常
@Test
public void testDelete(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 10);
session.delete(user);
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是get()方法,它可以從數據庫中獲取數據,獲取到的對象是持久化狀態。第10行通過id獲取一個User對象,此時會直接執行select語句,如果打印出SQL語句的話,會看到先打印出select語句,再打印出“====”,如果查找的對象不存在,就返回null。
//get():獲取數據,是持久化狀態
//會馬上執行SQL語句
//如果對象不存在,就返回null
@Test
public void testGet(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 11);
System.out.println("====");
System.out.println(user.getName());
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是load()方法,它可以從數據庫中獲取數據,獲取到的對象是持久化狀態。load方法返回的是一個代理對象,如果此時打印出user.getClass.getName(),就會發現其類型不是自己定義的User類型了,而是一個User的代理對象。第16行打印user的name屬性,此時纔會執行select語句查詢數據庫,這是hibernate懶加載的特性。
//load():獲取數據,是持久化狀態
//load後返回的是一個代理對象,要求類不能是final的,否則不能生成子類代理,就不能使用懶加載功能
//讓懶加載失效的方式:
// 一、把實體類寫成final
// 二、在hbm.xml的<class>配置lazy="false"
//不會馬上執行SQL語句,而是在第一次使用非id和class屬性時執行sql
//如果對象不存在,就拋異常:org.hibernate.ObjectNotFoundException
@Test
public void testLoad(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.load(User.class, 11);
System.out.println("=====");
System.out.println(user.getName());
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是批量保存,Session緩衝區是由一定的大小的,如果存放過多的對象,可能會導致內存溢出。所以第13行採取的方法是每保存15個對象,就調用一次flush把對象刷出到數據庫,然後清空session,這樣就防止了內存溢出的問題。
//操作大量數據,要防止Session中對象過多而內存溢出
@Test
public void testBatchSave(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
for(int i = 0; i < 100; i++){
User user = new User();
user.setName("測試");
session.save(user);
if(i % 15 ==0){
session.flush(); //先刷出
session.clear(); //再清空
}
}
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}