目錄
1.概述
1.1對象持久化的3中方式
①序列化對象,將對象存儲到格式化的文本文件中。
②將對象持久化到xml文檔中。
③將對象持久化到數據庫中,一般爲關係型數據庫。
1.2對象關係映射ORM
ORM(Object/Relation Mapping)實現了java應用中的對象到關係型數據庫中表的自動持久化,並使用元數據來描述對象和數據庫之間的映射關係。元數據通常採用xml格式。
1.3Hibernate工作原理
// 1.造對象
Employee emp = new Employee();
emp.setEmpName("班長");
emp.setWorkDate(new Date());
// 獲取加載配置文件的管理類對象
Configuration config = new Configuration();
config.configure(); // 默認加載src/hibenrate.cfg.xml文件
// 創建session的工廠對象
SessionFactory sf = config.buildSessionFactory();
// 創建session (代表一個會話,與數據庫連接的會話)
Session session = sf.openSession();
//2.用session.save()保存到數據庫
// 開啓事務
Transaction tx = session.beginTransaction();
//保存-數據庫
session.save(emp);
// 提交事務
tx.commit();
// 關閉
session.close();
sf.close();
2.核心接口
2.1 Configuration類
作用:
對Hibernate進行配置,啓動hibernate並連接數據庫系統。
在hibernate的啓動過程中,Configuration的實例首先找到xml的配置文件hibernate.cfg.xml,讀取相關的配置信息,然後創建一個唯一的SessionFactory對象。
一般一個項目只需要一個Configuration類,如果項目中需要訪問多個數據庫,就需要創建多個Configuration實例,以此來爲每個數據庫都創建一個SessionFactory實例。
常用方法:
Configuration config=new Configuration().configure(); 默認加載src/hibernate.cfg.xml。
Configuration config=new Configuration().configure(“cn/config/hibernate.cfg.xml”); 加載指定路徑下的主配置文件。
SessionFactory sessionFactory=config.buildSessionFactory(); 創建SessionFactory實例
2.2 SessionFactory接口
作用:
負責Hibernate的初始化。SessionFactory接口作爲數據存儲源的代理,負責建立session對象。
一般一個項目只需要一個SessionFactory接口,如果項目中需要訪問多個數據庫,就需要創建多個Configuration實例,以此來爲每個數據庫都創建一個SessionFactory實例。
特點:
①線程安全,同一實例可以供多個線程共享。
②重量級,不能隨意創建和銷燬它的實例。
常用方法:
Session session=sessionFactory.openSession(); 創建一個sesison對象
Session session=sessionFactory.getCurrentSession(); 創建session或取出session對象
區別:
openSession()直接創建一個新的Session實例;使用後,需代用session.close()方法手動關閉。
getCurrentSession()創建的Session實例會被綁定到當前線程中;在提交(commit)或回滾(rollback)時,會自動關閉。
2.3 Session接口
作用:
Session接口是Hibernate中使用最廣泛的接口,也是持久化操作的核心。
Session對象的生命週期以Transaction對象的事務開始和結束爲界。Session提供了一系列與持久化相關的 操作。
特點:
①線程非安全,應避免多個線程共享一個Session實例。
②輕量級,實例的創建和銷燬不需要太多的資源。
③有一個緩存,即Hibernate的一級緩存。用於存放當前工作單元加載的對象。
常用方法:
session.save(user) ,將對象加入緩存,並保存到數據庫中
session.update(user),將對象加入緩存,並更新數據庫中的數據。(此方法必須爲對象設置主鍵)
session.saveOrUpdate(user),若沒有設置主鍵,執行保存;若設置了主鍵,執行更新;若設置的主鍵不存在,則報錯。
session.delete(user)刪除緩存中的記錄,並刪除數據庫中的記錄。(此方法必須爲對象設置主鍵)
session.get(User.class,id)通過標識符得到指定類的持久化對象。
session.load(User.class,id)通過標識符得到指定類的持久化對象。
session.contains(user)判斷session緩存中是否有指定對象。
session.evict(user)移除session緩存中指定對象(通常先用contains方法判斷,再移除)
session.clear()清空session緩存中的全部對象。
Transaction tx = session.beginTransaction();開啓事務
創建查詢對象的方法:
Query query=session.createQuery("from User"); HQL(Hibernate Query language)語句查詢
Criteria criteria = session.createCriteria(User.class); Criteria語句查詢
SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM t_Dept limit 5;").addEntity(Dept.class); SQL語句查詢
2.4 Transaction接口
作用:
Transaction接口用於事務管理,它對底層的事務接口(如:JDBC API)進行了封裝。用戶可以利用Transaction對象定義自己的原子操作。Session執行完數據庫操作後,要使用Transaction進行事務的提交後,才能真正將數據操作同步到數據庫中。
常用方法:
tx.commit(); 提交事務
tx.rollback(); 事務回滾
3.總結
3.1對象的三種狀態
Hibernate中對象的狀態: 臨時/瞬時態(Transient)、持久態(Persistent)、遊離態(Detached)。
- 瞬時態
使用new操作符初始化的對象不是立刻就持久化的,他們的狀態是瞬時的。
特點:
(1) 不處於Session的緩存中,即不被任何一個Session實例關聯。
(2) 在數據庫中沒有對應的記錄。
- 持久態
當調用session的save/saveOrUpdate/get/load等方法的時候,對象就是持久態。處於持久化狀態的對象,當對對象屬性進行更改的時候,會反映到數據庫中!
特點:
(1) 處於Session的緩存中,被當前Session實例關聯。
(2) 在數據庫中有對應的記錄。
- 遊離態
Session關閉後,持久化對象就變爲遊離對象;
特點:
(1) 不處於Session的緩存中,即不被任何一個Session實例關聯。
(2) 在數據庫中有對應的記錄。
//創建瞬時態對象
User user=new User();
user.setName("xiaohua");
user.setPassword("123");
//user 對象處於瞬時態
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(user);//調用save方法
//此時已處於持久態
tx.commit();
session.close();//調用close方法
//此時處於遊離態
對象狀態轉換圖:
3.2 get、load的區別
①get()如果沒有找到持久化類返回null;
load()如果沒有找到持久化類直接拋出異常。ObjectNotFoundEcception
②get()是直接返回實體類。不論*.hbm.xml文件中<class>元素的的lazy屬性是true還是false。
當調用load()方法的時候,若*.hbm.xml文件中<class>元素的的lazy屬性爲true,則會返回一個目標對象的代理對象,在這個代理對象中只存儲了目標對象的ID值,其他都爲null值,只有當調用除ID值以外的屬性值的時候纔會發出SQL查詢。(即load方法採用延遲加載)
當調用load()方法的時候,若*.hbm.xml文件中<class>元素的的lazy屬性爲false,則是直接返回實體類。
總結:
使用get加載,hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,然後在二級緩存中查找,還沒有就查數據庫,數據庫中沒有就返回null。
使用load加載,Hibernate會認爲該id對應的對象是一定存在的,所以它可以放心的使用,它可以放心的使用代理來 延遲加載該對象。在用到對象中的其他屬性數據時才查詢數據庫,但是萬一數據庫中不存在該記錄,那沒辦法,只能拋異常。