您好,登錄后才能下訂單哦!
使用Hibernate最大的目的就是對數據庫進行crud操作。在講解之前,我們需要了解持久化以及持久化對象的三種狀態。
?
持久化就是把內存中的數據永久的存儲到數據庫中
?
持久化類就是Java類與數據庫建立的一種映射關系,并把這個類稱做持久化類。實際上,就是一張數據表中的字段與類中的屬性字段相對象的類。
?
1.需要提供無參數的構造方法
??因為Hibernate通過反射機制生成類的實例
2.需要私有屬性,并提供對應的get和set方法
??因為Hibernate底層會對獲取到的數據驚醒封裝
3.屬性盡量使用包裝類類型
?? 區分空和null
4.類中必須存在一個唯一標識 OID與表中的主鍵對應
?? Hibernate利用這個這個唯一標識來區分內存中是否是同一個持久化類
5.不要使用final修飾類
??因為Hibernate有加載延遲機制,這個機制會產生代理對象。代理對象是通過字節 碼增強技術來完成的,其實就是通過產生子類的方式,如果使用final修飾持久化類,這個機制就會失敗。加載延遲機制是一種優化的手段。
?
主鍵的類型
- 自然主鍵
把具有業務含義的字段作為主鍵,稱為自然主鍵。比如,客戶的姓名(必須保證姓名不重復,唯一,非空),這類主鍵往往會因為業務的改變重新設計表,造成數據庫維護困難。- 代理主鍵
把具有非業務字段作為主鍵,稱為代理主鍵。通常是ID,類型是整數類型(比字符串節省空間)- Hibernate提供了幾個內置主鍵生成策略
1.increment:用于short int long類型。以自動增長的方式,每次增量是1。
2.identity:采用底層數據庫本身提供的主鍵生成標識,前提是數據庫支持自動增長的類型。
3.sequence:Hibernate根基底層序列生成標識符,前提是數據庫支持序列。
4.native:根據底層數據庫生成能力來判斷生成identity、sequence、hilo中的一種。適合跨數據庫開發。
5.uuid:采用128位uuid算法生成標識符
6.assigned:由Java程序負責生成標識符。如果不指定id的generator屬性,默認使用該屬性。適合自然類型。
?
下面通過列舉例子來說明上述內容
@Test
public void demo() {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// 瞬時態,此時沒有OID,也沒有與session關聯
User user = new User();
user.setUsername("robin");
Serializable save = session.save(user); // 持久態
transaction.commit();
session.close();
sessionFactory.close();
// 托管態,此時session關閉,沒有與session關聯,但是有OID
System.out.println(user);
}
轉換關系
?
瞬時態
1.瞬時態 -- 持久態
??調用save()或者saveOrUpdate()
2.瞬時態 -- 托管態
??為瞬時態添加 OID
?
持久態:可以從Session get() load()方法獲取,或者Query對象等
1.持久態 -- 瞬時態
??session.delete()刪除持久態化對象
2.持久態 -- 托管態
??session.evict()、clear()、close()方法。evict()用于清除一級緩存中的某一個對象,clear()用于清除一級緩存中的所有對象, close()關閉session,并且清除一級緩存。
?
托管態
1.托管套 -- 持久態
??執行update()、saveOrUpdate() lock()等
2,托管態 -- 瞬時態
??把對象的OID設置為null
?
依賴Hibernateu一級緩存
@Test
public void demo() {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
User user = session.get(User.class, 2);
user.setUsername("Robin");
// session.update(user); 這句話可以省略,因為持久態的對象會自動更新數據庫
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}
}
?
緩存是計算機為了提高讀取速度而設計的。通常介于應用程序和永久性存儲介質之間。提高應用的運行能力,通常是內存。
?
Hibernate緩存分為一級緩存和二級緩存(redis替代),一級緩存是Hibernate內置緩存,不能刪除。
?
Hibernate一級緩存實際上就是session緩存。Session緩存是一個內存空間,存放相互管理的Java對象。在使用對象查找的時候,會使用OID在Hibernate一級緩存中進行查找,如果查找到了,就返回此對象,否則,就會去數據庫查找與之相同OID的對象。
?
只要session實例沒有結束生命周期,存放在它上面的緩存也不會消失。
一級緩存的特點
當應用程序調用Session的save()、update、saveOrUpdate()的時候,Session緩存中沒有相應的對象的時候,Hibernate會自動的從數據庫中提取對應的數據加載到一級緩存中
當應用程序調用Session load()、get(),以及Query中的、list()、iterator()的時候,Hibernate首先會從以及緩存中尋找對象,如果存在則不需要去數據庫中查找。,如果沒有則從數據庫中獲取并加載到一級緩存中
當調用Session.close()的時候,session緩存會被清空。
?
觀察控制臺輸出的SQL語句
@Test
public void demo() {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
/**
* 查詢兩次
*/
/**
* 第一次執行你會查詢數據庫
* 第二次查詢只會去緩存中尋找
*/
User user = session.get(User.class, 1);
User user1 = session.get(User.class, 1);
transaction.commit();
session.close();
sessionFactory.close();
}
?
Hibernate向一級緩存中存儲數據的時候,會拷貝一份數據放在Hibernate快照區,當使用事務提交之后,會根據OID比較一級緩存中的數據和快照區中的數據是否一致,如果不一致,則執行更新操作,并且同步快照區的數據,否則則不執行任何操作。
?
?
?
?
在業務層處理事務的方法
1.在業務層中獲取session,把它傳遞給持久層
2.使用ThreadLocal將業務層獲取到的session綁定到當前線程中去。然后到業務層獲取的時候獲取當前線程的session.
<property name="hibernate.current_session_context_class">thread</property>
sessionFactory.getCurrentSession()
可以不需要關閉session,線程結束之后會自動關閉
thread: Session對象的生命周期與本地線程綁定
jta:Session對象的生命周期與JTA事務綁定
managed:Hinernate委托程序來管理Session對象的生命周期
?
??
Query是面對對象的Hibernate查詢操作。通過session.createQuery(),傳遞一個HQL語句,獲取Query對象。
@Test
public void demo() {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
/**
* 創建Query
* 調用對象的方法
*/
Query query = session.createQuery("from User");
List<User> list = query.list();
for (User user : list) {
System.out.println(user);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}
Criteria是一個完全面對對象,可擴展的條件查詢API,它不需要考慮數據庫底層的實現,以及SQL語句的編寫。它是Hibernate核心查詢對象,又稱為OBC(Object By Criteria)
@Test
public void demo() {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
/**
* Criteria
* 創建Criteria對象
* 調用方法
*/
Criteria criteria = session.createCriteria(User.class);
List<User> list = criteria.list();
for (User user : list) {
System.out.println(user);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}
SQLQuery用來接收SQL語句,需要我們手動封裝數據
@Test
public void demo03() {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
/**
* 對象
* 調用方法
*/
String sql = "select * from `tb_user`";
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.addEntity(User.class);
List<User> list = sqlQuery.list();
// List<Object[]> list = sqlQuery.list();
// for (Object[] user : list) {
// System.out.println(Arrays.toString(user));
// }
for (User user : list) {
System.out.println(user);
}
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。