①.對JDBC訪問數據庫的代碼作了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。
② .Hibernate 是一個基於JDBC的主流持久化框架,是一個優秀的ORM 實現。他很大程度 的簡化DAO層的編碼工做
③ .hibernate 的性能很是好,由於它是個輕量級框架。映射的靈活性很出色。它支持各種關係數據庫,從一對一到多對多的各類複雜關係。
(1)hibernate支持兩個級別的緩存,默認只支持一級緩存;
(2)每一個Session內部自帶一個一級緩存;
(3)某個Session被關閉時,其對應的一級緩存自動清除;
(1) 二級緩存獨立於session,默認不開啓;
Integer是對象. code=null; 對象能夠爲空.
int 是普通類型, 不可能=null.
由於HQL是面向對象的,而對象類的名稱和屬性都是大小寫敏感的,因此HQL是大小寫敏感的。HQL語句:from Cat as cat where cat.id > 1;與from Cat as cat where cat.ID > 1;是不同的,這點與SQL不一樣。
from Cat,該句返回Cat對象實例,開發人員也能夠給其加上別名,eg. from Cat as cat,對於多表查詢的狀況,可參考以下:from Cat as cat, Dog as dog其它方面都與SQL相似,在此再也不贅述。
①必須提供無參數public構造器
②全部屬性private,提供public的getter和setter方法
③必須提供標識屬性,與數據表中主鍵對應,例如Customer類 id屬性
④PO類屬性應儘可能使用基本數據類型的包裝類型(區分空值) 例如int---Integer long---Long
⑤不要用final修飾(將沒法生成代理對象進行優化)
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
Book book =newBook();// 瞬時態(沒有OID,未與Session關聯)
book.setName("hibernate精通");
book.setPrice(56d);
session.save(book);// 持久態(具備OID,與Session關聯)
// 提交事務,關閉Session
transaction.commit();
session.close();
System.out.println(book.getId());// 脫管態(具備 OID,與Session斷開關聯)
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JTATransactionFactory
#hibernate.transaction.factory_class net.sf.hibernate.transaction.JDBCTransactionFactory
Session session = sf.openSession();
Transaction tx = session.beginTransactioin();
...
session.flush();
tx.commit();
session.close();
net.sf.hibernate.transaction.JDBCTransaction:
public void begin() throws HibernateException {
...
if (toggleAutoCommit) session.connection().setAutoCommit(false);
...
}
public void commit() throws HibernateException {
...
try {
if ( session.getFlushMode()!=FlushMode.NEVER ) session.flush();
try {
session.connection().commit();
committed = true;
}
...
toggleAutoCommit();
}
Connection conn = ...; <--- session = sf.openSession();
conn.setAutoCommit(false); <--- tx = session.beginTransactioin();
... <--- ...
conn.commit(); <--- tx.commit(); (對應左邊的兩句)
conn.setAutoCommit(true);
conn.close(); <--- session.close();
//方式一:
去src 讀取 hibernate.properties 屬性配置文件
Configuration cfg =newConfiguration();
//方式二:去src讀取 hibernate.cfg.xml
Configuration cfg =newConfiguration().configure();
Configuration cfg =newConfiguration().configure("自定義xml文件");去src 加載指定文件
org.hibernate.MappingException:Unknown entity: cn.itcast.domain.Customer
//方式一:
configuration.addResource("cn/itcast/domain/Customer.hbm.xml");加載hbm文件
//方式二:
configuration.addClass(Customer.class);加載Class,自動搜索hbm映射文件
//預約義SQL語句
<sql-queryname="login">
<![CDATA[select * from user where username= ? and password =?]]>
</sql-query>
save 完成插入
update 完成修改
delete完成刪除
get/load 根據主鍵字段查詢
createQuery、 createSQLQuery 建立查詢對象Query接收HQL,SQLQuery接收SQL
createCriteria() 面向對象條件查詢
//默認false
<property name="hibernate.connection.autocommit">false</property> 事務不提交
<propertyname="hibernate.connection.autocommit">true</property> 事務提交
開發代碼步驟
得到HibernateSession對象
編寫HQL語句
調用session.createQuery 建立查詢對象
若是HQL語句包含參數,則調用Query的setXXX設置參數
調用Query對象的list()或uniqueResult()方法執行查詢
*private transient ActionQueue actionQueue; ----行動隊列(標記數據活動)
*private transient StatefulPersistenceContext persistenceContext;----持久化上下文
Book book =(Book) session.get(Book.class,1);// 第一次查詢,緩存中沒有
System.out.println(book);
Book book2 =(Book) session.get(Book.class,1);// 由於第一次查詢,對象已經被放入1級緩存,不會查詢數據
System.out.println(book2);
*生成一條SQL語句,返回同一個對象,第一次查詢生成SQL,查詢對象,將對象放入一級緩存,第二次查詢,直接從一級緩存得到
* 測試快照區的使用
*/
@Test
publicvoid demo3(){
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
// 查詢id 爲1 的圖書對象
Book book =(Book) session.get(Book.class,1);// 第一次查詢,將對象加入一級緩存
System.out.println(book);
book.setName("深刻淺出Hibernate技術");// 修改書名(一級緩存被修改,自動update)
// 沒有手動執行update,由於快照區緣由,自動更新
// 提交事務,關閉Session
transaction.commit();
session.close();
@Test
// Session 對於 一級緩存操做
publicvoid demo4(){
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
// 查詢id 爲1 的圖書對象
Book book =(Book) session.get(Book.class,1);// 第一次查詢,將對象加入一級緩存
System.out.println(book);
// book.setPrice(80d); // 修改一級緩存數據
// 將緩存內容同步到數據庫
// session.flush();
// 清除一級緩存全部數據
// session.clear();
// 清除一級緩存中 指定對象
// session.evict(book);
book.setPrice(30d);// 一級緩存改變
session.refresh(book);// 用數據庫內容 覆蓋快照區和一級緩存
// 提交事務,關閉Session
transaction.commit();
session.close();
}
@Test
// 理解 FlushMode做用
publicvoid demo5(){
// 得到Session
Session session =HibernateUtils.openSession();
// 設置 flushMode
session.setFlushMode(FlushMode.MANUAL);
// 開啓事務
Transaction transaction = session.beginTransaction();
// 查詢id 爲1 的圖書對象
Book book =(Book) session.get(Book.class,1);// 第一次查詢,將對象加入一級緩存
System.out.println(book);
book.setPrice(1000d);// 修改價格
session.createQuery("from Book").list();// 查詢全部圖書 (AUTO 級別 flush)
// 提交事務,關閉Session
transaction.commit();// (COMMIT 級別 flush)
// session.flush(); // MANUAL 級別 flush
session.close();
}
@Test
// 脫管對象更新
publicvoid demo6(){
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
Book book =newBook();// 瞬時
book.setId(1);// 脫管
book.setName("java入門");
book.setPrice(40d);
session.update(book);// 持久
session.flush();
// book.setPrice(50d);
// 提交事務,關閉Session
transaction.commit();
session.close();
}
<classname="cn.itcast.domain.firstcache.Book"table="book"catalog="hibernate3day2"select-before-update="true">
@Test
// 一級緩存 存在兩個相同OID 持久態對象 報錯
publicvoid demo7(){
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
// 查詢
// Book b = (Book) session.get(Book.class, 1); // 持久
Book book =newBook();// 瞬時
book.setId(1);// 脫管
book.setName("java入門");
book.setPrice(50d);
session.update(book);// 持久
// 提交事務,關閉Session
transaction.commit();
session.close();
}
@Test
// PO對象,OID爲 hbm文件 配置 unsaved-value 也是瞬時對象, saveOrUpdate 執行 save操做
publicvoid demo8(){
// 得到Session
Session session =HibernateUtils.openSession();
// 開啓事務
Transaction transaction = session.beginTransaction();
Book book =newBook();// 瞬時
book.setId(-1);// 存在OID , -1是unsaved-value 也是瞬時
book.setName("xxx");
book.setPrice(100d);
session.saveOrUpdate(book);
// 提交事務,關閉Session
transaction.commit();
session.close();
}
緩存好處: 將數據庫或者硬盤數據,保存在內存中,減小數據庫查詢次數,減小硬盤交互,提升檢索效率java
hibernate 共有兩個級別的緩存 web
* 一級緩存,保存Session中, 事務範圍的緩存sql
* 二級緩存,保存SessionFactory ,進程範圍的緩存數據庫
SessionFacoty 兩部分緩存緩存
內置 :Hibernate 自帶的, 不可卸載. 一般在 Hibernate 的初始化階段, Hibernate 會把映射元數據和預約義的 SQL 語句放到 SessionFactory 的緩存中, 映射元數據是映射文件中數據的複製, 而預約義 SQL 語句時 Hibernate 根據映射元數據推到出來的. 該內置緩存是隻讀的.安全
外置 :一個可配置的緩存插件. 在默認狀況下, SessionFactory 不會啓用這個緩存插件. 外置緩存中的數據是數據庫數據的複製, 外置緩存的物理介質能夠是內存或硬盤,必須引入第三方緩存插件才能使用。session
** 一級緩存的操做會同步到二級緩存併發
更新時間戳區域app
做用:記錄數據最後更新時間,確保緩存數據是有效的框架
Hibernate 提供了和查詢相關的緩存區域:
* 二級緩存緩存數據都是類對象數據,數據都是緩存在 "類緩存區域" ,二級緩存緩存PO類對象,條件(key)是id
查詢緩存適用場合:
**應用程序運行時常用查詢語句
**不多對與查詢語句檢索到的數據進行插入, 刪除和更新操做
若是查詢條件不是id查詢, 緩存數據不是PO類完整對象 =====> 不適合使用二級緩存
查詢緩存: 緩存的是查詢數據結果, key是查詢生成SQL語句 , 查詢緩存比二級緩存功能更增強大
2)啓用查詢緩存 hibernate.cfg.xml
<property name="hibernate.cache.use_query_cache">true</property>
query.setCacheable(true);
transactional : 提供Repeatable Read事務隔離級別,緩存支持事務,發生異常的時候,緩存也可以回滾
read-write : 提供Read Committed事務隔離級別,更新緩存的時候會鎖定緩存中的數據
nonstrict-read-write :致使髒讀, 不多使用
read-only : 數據不容許修改,只能查詢
* 不多被修改,不是很重要,容許偶爾的併發問題, 適合放入二級緩存。考慮因素(二級緩存的監控【後面學習】,它是是否採用二級緩存主要參考指標)