hibernate實體的狀態 實體Entity有三種狀態,瞬時狀態,持久狀態,脫管狀態 瞬時狀態:transient,session 沒有緩存,資料庫也沒有記錄,oid沒有值 持久狀態:persistent,session有緩存,資料庫也有記錄,oid有值 脫管狀態:detached,session ...
hibernate實體的狀態
實體Entity有三種狀態,瞬時狀態,持久狀態,脫管狀態
瞬時狀態:transient,session 沒有緩存,資料庫也沒有記錄,oid沒有值
持久狀態:persistent,session有緩存,資料庫也有記錄,oid有值
脫管狀態:detached,session沒有緩存,資料庫有記錄,oid有值
瞬時狀態轉持久狀態
public void test1(){
Configuration cfg = new Configuration().configure();
//創建會話工廠
SessionFactory factory = cfg.buildSessionFactory();
//獲取session對象
Session session = factory.openSession();
session.getTransaction().begin();
//創建一個對象,這個對象就是瞬時狀態
User user = new User("迪麗熱巴","123");//沒有id,資料庫沒有數據session沒有緩存
System.out.println(user);//User [uid=0, username=迪麗熱巴, password=123]
session.save(user);//經過保存後,這個對象就是持久狀態,id有值,資料庫有數據,session有緩存
System.out.println(user);//User [uid=1, username=迪麗熱巴, password=123]
session.getTransaction().commit();
session.clear();
}
持久狀態轉脫管狀態
public void test2(){
Configuration cfg = new Configuration().configure();
//創建會話工廠
SessionFactory factory = cfg.buildSessionFactory();
//獲取session對象
Session session = factory.openSession();
session.getTransaction().begin();
//通過get方法可以獲取一個持久狀態對象
User user = (User) session.get(User.class,1);//執行select語句
System.out.println(user);
User user1 = (User) session.get(User.class,1);//不執行select語句,因為有session緩存
System.out.println(user1);
session.getTransaction().commit();
session.clear();
}
把持久狀態轉脫管狀態需要使用session.clear方法
User user = (User) session.get(User.class,1);//執行select語句
System.out.println(user);
session.clear();//清除session
User user1 = (User) session.get(User.class,1);//執行select語句,因為沒有session緩存
System.out.println(user1);
執行兩次select
Hibernate:
select
user0_.id as id0_0_,
user0_.username as username0_0_,
user0_.password as password0_0_,
user0_.birthday as birthday0_0_
from
t_user user0_
where
user0_.id=?
User [uid=1, username=迪麗熱巴, password=123]
Hibernate:
select
user0_.id as id0_0_,
user0_.username as username0_0_,
user0_.password as password0_0_,
user0_.birthday as birthday0_0_
from
t_user user0_
where
user0_.id=?
User [uid=1, username=迪麗熱巴, password=123]
一級緩存,快照,一級緩存刷新
一級緩存:又稱為session級別的緩存,當獲得一側會話(session),hibernate在session中創建多個集合(Map),用於存放操作數據(PO對象),為程式優化服務,如果之後需要相應的數據,hibernate優先從session緩存中獲取,如果有就使用:如果沒有在查詢資料庫,當session關閉時,一級緩存銷毀
快照:與一級緩存一樣的存放位置,對一級緩存數據備份,保證資料庫的數據與一級緩存的數據必須一致。如果一級緩存修改了,在執行commit提交時,將自動刷新一級緩存,執行update語句,將一級緩存的數據更新到資料庫
使用HQL會對數據進行一級緩存,使用SQL不會對數據進行緩存
Query query = session.createQuery("from User");//HQL對數據進行一級緩存
List<User> list = query.list();
User user = (User)session.get(User.class,1);//有緩存,不用執行select語句,就能獲取數據
save和persist方法區別
save方法:瞬時態 轉換 持久化 會初始化OID
執行save方法前,設置OID將忽略
如果執行查詢,session緩存移除了,在執行save方法,將會執行insert
public void test1(){
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
session.getTransaction().begin();
User user = new User("迪麗熱巴","123");
user.setUid(13);
System.out.println(user);//[uid=13, username=迪麗熱巴, password=123]
//執行save方法前,設置的OID將會忽略,
session.save(user);//瞬時態轉持久態,執行save方法會立即出發insert語句,從資料庫獲取主鍵的值
System.out.println(user);//User [uid=1, username=迪麗熱巴, password=123]
//執行session.clear,將會把緩存移除,再次執行save方法,將會執行insert,sql語句
session.clear();
session.save(user);//再次保存,id會自動增長
System.out.println(user);//[uid=2, username=迪麗熱巴, password=123]
session.getTransaction().commit();//當事務提交時會自動自行update語句
session.clear();
}
persist方法:瞬時態,轉換持久態
persist保存的對象,在保存前,不能設置id,否則會報錯
save和persist都是持久化對象的作用
save因為需要返回一個主鍵值,因此會立即執行Insert語句,
而persist在事務外部調用是則不會立即執行insert語句
在事務內部調用還是會立即執行insert語句的
public void test1(){
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
session.getTransaction().begin();
User user = new User("古娜力扎","123");
//user.setUid(30);persist保存的對象,在保存前,不能設置id,否則會報錯
session.persist(user);//該方法在事務外不會執行insert sql語句
session.getTransaction().commit();//當事務提交時會自動自行update語句
session.clear();
}
一對多實體類和映射文件
多表關係
多對多:比如老師對應多個學生,學生對應多個老師,有中間表的關係
一對多:一個客戶對應多個訂單,表之間有主表和從表,之間的關係(主外鍵關係)
一個客戶對應多個訂單
客戶與訂單文件的映射
<!--
描述一對多的關係
key中column寫的是外鍵名稱
one-to-many:一對多,裡面寫的class,寫多的一方
-->
<set name="orders">
<key column="customer_id"></key>
<one-to-many class="domain.Order"></one-to-many>
</set>
<!--描述customer的關係
class寫一的一方
column:寫外鍵
-->
<many-to-one name="customer" class="domain.Customer" column="customer_id"/>