下午湯陽光提供了以下幾種檢索對象的方式_第1頁
下午湯陽光提供了以下幾種檢索對象的方式_第2頁
下午湯陽光提供了以下幾種檢索對象的方式_第3頁
下午湯陽光提供了以下幾種檢索對象的方式_第4頁
下午湯陽光提供了以下幾種檢索對象的方式_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、1. Hibernate 檢索1.1. hibernate 檢索方式說明Hibernate 提供了以下幾種檢索對象的方式導(dǎo)航對象圖檢索方式:根據(jù)已經(jīng)加載的對象導(dǎo)航到其他對象OID 檢索方式: HQL 檢索方式:QBC 檢索方式:按照對象的 OID 來檢索對象使用面象的 HQL 查詢語言使用 QBC(Query By Criteria) API 來檢索對象.這種 API 封裝了基于字符串形式的查詢語句, 提供了更加面象的查詢接口.本地 SQL 檢索方式: 使用本地數(shù)據(jù)庫的 SQL 查詢語句1.2. HQL 檢索方式HQL(Hibernate Query Language) 是面象的查詢語言, 它

2、和SQL 查詢語言有些相似. 在 Hibernate 提供的各種檢索方式中, HQL 是使用最廣的一種檢索方式. 它有如下功能:在查詢語句中設(shè)定各種查詢條件支持投影查詢, 即僅檢索出對象的部分屬性支持分頁查詢支持連接查詢支持分組查詢, 允許使用 HAVING 和 GROUP BY 關(guān)鍵字提供內(nèi)置函數(shù), 如 sum(), min() 和 max()能夠調(diào)用 用戶定義的 SQL 函數(shù)或標(biāo)準(zhǔn)的 SQL 函數(shù)支持子查詢支持動態(tài)綁定參數(shù)HQL 檢索方式包括以下步驟:通過 Ses的 createQuery() 方法創(chuàng)建一個 Query 對象, 它包括一個 HQL 查詢語句. HQL 查詢語句中可以包含命名

3、參數(shù)動態(tài)綁定參數(shù)調(diào)用 Query 的 list() 方法執(zhí)行查詢語句. 該方法返回 java.util.List 類型的查詢結(jié)果,在 List 集合中存放了符合查詢條件的持久化對象.Qurey 接口支持方法鏈編程風(fēng)格, 它的 set() 方法返回自身實例, 而不是 void 類型HQL vs SQL:HQL 查詢語句是面象的, Hibernate 負(fù)責(zé)HQL 查詢語句, 然后根據(jù)對象-關(guān)系文件中的信息, 把 HQL 查詢語句翻譯成相應(yīng)的 SQL 語句. HQL 查詢語句中的主體是域模型中的類及類的屬性SQL 查詢語句是與關(guān)系數(shù)據(jù)庫綁定在一起的. SQL 查詢語句中的主體是數(shù)據(jù)庫表及表的字段.H

4、QL 的語法類似 SQL 語法。1.2.1. 綁定參數(shù)Hibernate 的參數(shù)綁定機(jī)制依賴于 JDBC API 中的 PreparedSement 的預(yù)定義 SQL語句功能.HQL 的參數(shù)綁定由兩種形式:按參數(shù)名字綁定: 在 HQL 查詢語句中定義命名參數(shù), 命名參數(shù)以 “:” 開頭.按參數(shù)位置綁定: 在 HQL 查詢語句中用 “?” 來定義參數(shù)位置相關(guān)方法:setEntity(): 把參數(shù)與一個持久化類綁定setParameter(): 綁定任意類型的參數(shù). 該方法的第三個參數(shù)顯式指定射類型Hibernate映綁定參數(shù)的形式,按參數(shù)名稱綁定綁定參數(shù)的形式,按參數(shù)位置綁定Query quer

5、y = ses.createQuery(from Customer =? and c.age=?); query.setString(0,Tom);query.seteger(1, 21); Query.list();hql 查詢:Query query = ses.createQuery(from Customer c where +=:custnameandc.age=:custage);/第一個參數(shù)代表名二個參數(shù)代表值 query.setString(custname, Tom); query.seteger(custage, 21);List lis

6、t = query.list();1.2.2. 使用別名通過 HQL 檢索一個類的實例時,如果查詢語句的其他地方需要指定一個別名它,應(yīng)該為這個類from Customer ascwhereas 可省略=:custname1.2.3. 排序HQL 采用 ORDER BY 關(guān)鍵字對查詢結(jié)果排序hql 查詢:Query query = ses.createQuery(from Customer c order by c.id);QBC 查詢:Criteria criteria = ses criteria.addOrder(.createCriteria(Customer.class);

7、.hibernate.criterion.Order.asc(“id);1.2.4. 分頁查詢:setResult(Result): 設(shè)定從哪一個對象開始檢索, 參數(shù)Result 表示這個對象在查詢結(jié)果中的索引位置, 索引位置的起始值為 0. 默認(rèn)情況下, Query 從查詢結(jié)果中的第一個對象開始檢索setMaxResult(maxResults): 設(shè)定一次最多檢索出的對象的數(shù)目. 在默認(rèn)情況下, Query和 Criteria 接口檢索出查詢結(jié)果中所有的對象1.2.5. 投影查詢投影查詢: 查詢結(jié)果僅包含實體的部分屬性. 通過 SELECT 關(guān)鍵字實現(xiàn).Query 的 list() 方法返

8、回的集合中包含的是數(shù)組類型的元素, 每個對象數(shù)組代表查詢結(jié)果的一條可以在持久化類中定義一個對象的構(gòu)造器來包裝投影查詢返回的全運用面象的語義來查詢結(jié)果集.可以通過 DISTINCT 關(guān)鍵字來保證查詢結(jié)果不會返回重復(fù)元素, 使程序代碼能完使用構(gòu)造函數(shù)/list集合中存放的對象數(shù)組,數(shù)組中存放的查詢的部分屬性Query query = ses.createQuery(select c.id,,o.orderNumber + from Customer cjoin c.orders owhere o.orderNumber like%NO1%);List list = query.list

9、(); Iterator it = list.iterator(); while (isNext() Object pair=(Object)it.next(); eger id=(egair0;String name=(String)pair1;String orderNumber=(String)pair2;System.out.pr(id + +name+orderNumber); System.out.prln();from Customer c join c.orders o where o.orderNumber like T%如果希望查詢結(jié)果中只包含Customer對象,可使用以

10、下形式:select c from Customer c join c.orders o where o.orderNumber like T%Select關(guān)鍵字還能用于選擇對象的部分屬性ses.createQuery(“select c.id,,o.orderNumber from Customer c join c.orders o where o.orderNumber like T%”)對應(yīng)的sql語句為:select c.ID,c.NAME,o.ORDER_NUMBER from CUSTOMERS c inner join ORDERS o on c.ID-=o.CUS

11、TOMER_ID where o.ORDER_NUMBER likeT%過濾重復(fù)元素createQuery(“select distinct from customer c”);1.2.6. 分組與函數(shù)報表查詢用于對數(shù)據(jù)分組和統(tǒng)計, 與 SQL 一樣, HQL 利用 GROUP BY據(jù)分組, 用 HAVING 關(guān)鍵字對分組數(shù)據(jù)設(shè)定約束條件.關(guān)鍵字對數(shù)HQL 查詢語句中可以調(diào)用以下count() min()max()sum()avg()在函數(shù)List list=ses.createQuery(select ,count(c)from Customer c group b

12、y ).list(); System.out.prln(list.size();Query query = ses.createQuery(select new cn.CustomerRow(c.id,,o.orderNumber) + from Customer cjoin c.orders owhere o.orderNumber like%NO1%); List list = query.list();Iterator it = list.iterator();while (isNext() CustomerRow cr=(CustomerRow)it.next(

13、);System.out.pr(cr.getId() + +cr.getName()+ +cr.getOrderNumber(); System.out.prln();1.2.7. 在文件中定義命名查詢語句1.2.8. 其他的查詢動態(tài)查詢:ses.createCriteria(Customer.class).add(Expres.like(“name”,name.toLowerCase(),Matode.ANYWHERE).query = ses.getNamedQuery(“findCustomersByName”); query.setString(“name”,”Tom”);query.

14、list();使用函數(shù)Query query = ses.createQuery(select count(*) from Customer c);/eger count=(eger)query.uniqueResult();/System.out.prln(count +count);/*/Query query = ses.createQuery(select avg(c.age) from Customer c);/Float avg=(Float)query.uniqueResult();/System.out.prln(avg +avg);/*/Queryquery=ses.crea

15、teQuery(selectmax(c.age),min(c.age)from Customer c);/Object maxmin=(Object)query.uniqueResult();/System.out.prln(max +(Long)maxmin0);/System.out.prln(min +(Long)maxmin1);/*/Query query = ses.createQuery(select sum(c.age) from Customer c);/Long sum=(Long)query.uniqueResult();/System.out.prln(sum +sum

16、);.add(Expres.eq(“age”,neweger(11);集合過濾:hql:createQuery(“from Order o where o.customer=:customer and o.price100 order by o.price”).setEntity(“customer”,customer).list();使用集合過濾:ses.createFilter(customer.getOrders(),”where this.price 100order by this.price”).list();子查詢:from Customer c where 1 Restrict

17、ions.ge大于等于=Restrictions.lt小于Restrictions.le小于等于=Restrictions.betn對應(yīng) sql 的 betn 子句Restrictions.like對應(yīng) sql 的 like 子句Restrictions.in對應(yīng) sql 的 in 子句Restrictions.andand 關(guān)系Restrictions.oror 關(guān)系Restrictions.sqlRestrictionSql 限定查詢1.5. 簡單的查詢/使用 hql 查詢Query query=ses List list=query.list();.createQuery(from Cu

18、stomer c where = tom1 );/使用 qbc 查詢主要由 Criteria、Criterion 接口和 Restrictions 類組成,他支持在運行時動態(tài)生成查詢語句。Criteria criteria=ses.createCriteria(Customer.class);/設(shè)定查詢條件,每個 Criterion 實例代表一個查詢條件Criterion cn1=Restrictions.eq(name, tom1); criteria.add(cn1);list=criteria.list();/方法鏈編程:ses.createCriteria(Custome

19、r.class).add(Restrictions.eq(name, tom1).list();1.6. HQL 和 QBC 支持的各種運算運算類型HQL 運算符QBC 運算方法比較運算=Restrictions.eq()Restrictions.not(Restrictions.eq()=Restrictions.ge()Restrictions.lt()=Restrictions.le()is nullRestrictions.isNull()is not nullRestrictions.isNotNull()范圍運算符inRestrictions.in()not inRestricti

20、ons.not(Restrictions.in()betnRestrictions.betn()not betnRestrictions.not(Restrictions.betn()字符串模式匹配likeRestriction.like()1.6.1. 小結(jié)2.事務(wù)和并發(fā)2.1. 數(shù)據(jù)庫的級別對于同時運行的多個事務(wù), 當(dāng)這些事務(wù)數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的機(jī)制, 就會導(dǎo)致各種并發(fā)問題: 臟讀: 對于兩個事物 T1, T2, T1了已經(jīng)被 T2 更新但還沒有被提交的字段. 之后, 若 T2 回滾, T1的內(nèi)容就是臨時且無效的.不可重復(fù)讀: 對于兩個事物 T1, T2, T1了一個

21、字段, 然后 T2 更新了該字段.幻讀:表中之后, T1 再次同一個字段, 值就不同了.對于兩個事物 T1, T2, T1 從一個表中了一些新的行. 之后, 如果 T1 再次了一個字段, 然后 T2 在該同一個表, 就會多出幾行.數(shù)據(jù)庫事務(wù)的性: 數(shù)據(jù)庫系統(tǒng)必須具有并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并發(fā)問題.一個事務(wù)與其他事務(wù)的程度稱為級別. 數(shù)據(jù)庫規(guī)定了多種事務(wù)級別, 不同級別對應(yīng)不同的干擾程度,級別越高, 數(shù)據(jù)一致性就越好, 但并發(fā)性越弱比較方面HQL 檢索QBC 檢索可讀性優(yōu)點:和 sql 相近,易讀將語句成一組 criteria,較差功能支持各種查詢不支持報表查詢

22、查詢。有限的連接查詢查詢語句形式基于字符串形式的 sql更加面象何時被運行時被編譯時被,更易排錯可擴(kuò)展性不具擴(kuò)展性用戶可擴(kuò)展 criteria 接口對動態(tài)查詢語句的支持支持動態(tài)查詢,編程麻煩適合動態(tài)生成查詢語句邏輯andRestriction.and()|Restriction.conjunction()orRestriction.or()|Restriction.disjunction()notRestriction.not()SQL ANSI SQL 標(biāo)準(zhǔn)定義了 4種事務(wù)級別,級別越高,成本越高:注:Oracle 只支持 2 種事務(wù)級別:READ COMMITED, SERIALIZABL

23、E. Oracle 默認(rèn)的事務(wù)級別為: READ COMMITED支持 4 中事務(wù)級別。默認(rèn)的事務(wù)級別為: REPEATABLE READ2.2. 在中設(shè)置級別每啟動一個程序, 就會獲得一個單獨的數(shù)據(jù)庫連接.每個數(shù)據(jù)庫連接都有一個全局變量 tx_isolation, 表示當(dāng)前的事務(wù)級別.為 Repeatable Read默認(rèn)的級別查看當(dāng)前的級別:當(dāng)前連接:SELECT tx_isolation;全局:SELECT global.tx_isolation;設(shè)置當(dāng)前連接的級別:set tran或 set sesion isolation level read committed;tranion i

24、solation level readmitted;設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的級別:set global tranion isolation level read committed;2.3. 在 Hibernate 中設(shè)置級別JDBC 數(shù)據(jù)庫連接使用數(shù)據(jù)庫系統(tǒng)默認(rèn)的級別. 在 Hibernate 的配置文件中可以顯式的設(shè)置級別. 每一個級別都對應(yīng)一個整數(shù):級別對應(yīng)的整數(shù)表示READMITED1READ COMMITED2REPEATABLE READ4SERIALIZEABLE8Hibernate 通過為 Hibernate級別。例:hibernate.connection.isolation

25、= 4文件指定 hibernate.connection.isolation 屬性來設(shè)置事務(wù)的注意Hibernate 不可能改變在受管環(huán)境下由應(yīng)用服務(wù)器提供的數(shù)據(jù)庫連接的過改變應(yīng)用服務(wù)器配置的方式來改變.級別,只能通設(shè)置級別是全局選項,會影響所有的連接和事務(wù)2.4. 管理 ses(CurrentSesContext)2.4.1. 關(guān)于管理 Ses管理 Ses對象的生命周期也是可行的, 但是在實際 Java 應(yīng)用中,盡管讓程序把管理 Ses架構(gòu)Hibernate 3對象的生命周期交給 Hibernate 管理, 可以簡化 Java 應(yīng)用程序代碼和自身提供了三種管理 Ses對象的方法 在 SesS

26、esSes對象的生命周期與本地線程綁定對象的生命周期與 JTA 事務(wù)綁定Hibernate 委托程序管理 Ses對象的生命周期Hibernate 的配置文件中, hibernate.current_ses_context_class 屬性用于指定管理方式,thread: Ses可選值包括對象的生命周期與本地線程綁定jta*: Ses對象的生命周期與 JTA 事務(wù)綁定managed: Hibernate 委托程序來管理 Ses對象的生命周期2.4.2. Ses對象的生命周期與本地線程綁定(通過Thread-localSes,線程本地化)如果把 Hibernate 配置文件的hibernate.c

27、urrent_ses_context_class 屬性值設(shè)為thread, Hibernate 就會按照與本地線程綁定的方式來管理 SesHibernate 按以下規(guī)則把 Ses與本地線程綁定當(dāng)一個線程(threadA)第一次調(diào)用 SesFactory 對象的 getCurrentSes() 方法時,A) 對象, 把該對象與 threadA 綁定, 并將該方創(chuàng)建一個新的 Ses(sessesA 返回當(dāng) threadA 再次調(diào)用 SesFactory返回 sesA 對象對象的 getCurrentSes() 方法時, 該方法將當(dāng) threadA 提交 sesA 對象關(guān)聯(lián)的事務(wù)時, Hiberna

28、te 會自動sesA 對象的緩存, 然后提交事務(wù), 關(guān)閉 sesA 對象. 當(dāng) threadA撤銷 sesA 對象關(guān)聯(lián)的事務(wù)時, 也會自動關(guān)閉 sesA 對象若 threadA 再次調(diào)用 SesFactory 對象的 getCurrentSes() 方法時, 該方又創(chuàng)建一個新的 Ses返回(sesB) 對象, 把該對象與 threadA 綁定, 并將 sesB配置:在 hibernate.cfg.xml 文件中增加thread不是調(diào)用 sesFactory.openSes().而是調(diào)用 sesFactory. getCurrentSes().獲取ses對象.從當(dāng)前的線程提取 ses:當(dāng)前線程如

29、果存在 ses當(dāng)前線程如果不存在 ses對象,取出直接使用對象,獲取一個新的 ses對象和當(dāng)前的線程綁定測試代碼:性能3.3.1. 使用連接池配置 c3p0 連接池* 引入 c3p0-0.9.1.jar3.2. Hibernate 的檢索策略3.2.1. hibernate 的檢索策略簡介類級別和關(guān)聯(lián)級別可選的檢索策略及默認(rèn)的檢索策略3.2.2. 區(qū)分立即檢索和延遲檢索檢索策略的作用域可選的檢索策略默認(rèn)的檢索策略運行時行為受影響的 ses的檢索方法類級別立即延遲延遲load關(guān)聯(lián)級別立即延遲迫切左外連接檢索延遲load get* 在 hibernate.cfg.xml 文件中增加如下配置.hib

30、ernate.connection.C3P0ConnectionProvid5201203000class中l(wèi)azy=true 延遲檢索public void loadCustomerTrue()Sesses=sesFacoty.openSes(); Tran ion tx=ses.begranion();Customer c=(Customer)ses.load(Customer.class, 1);/該行代碼讓hibernate執(zhí)行select語句,/查詢數(shù)據(jù)庫(需要用的時候查數(shù)據(jù)庫) c.getAge();mit();ses.close();Class中l(wèi)azy=false 立即檢索pu

31、blic void loadCustomerFalse()Sesses=sesFacoty.openSes(); Tranion tx=ses.begranion();/該行代碼讓hibernate執(zhí)行select語句,查詢數(shù)據(jù)庫Customer c=(Customer)ses.load(Customer.class, 1); c.getAge();mit();ses.close();3.2.3.理解延遲檢索中的對象的類名如下所示:Hibernate 使用 javassist-3.9.0.GA.jar 包創(chuàng)建值,其他的值不初始化)。Customer 對象對象(初始化 oid 的public v

32、oid loadCustomertrueProxy()Sesses=sesFacoty.openSes(); Tranion tx=ses.begranion();/此時查詢到的c對象是一個對象Customer c=(Customer)ses.load(Customer.class, 1); System.out.prln(c.getClass().getName();/對象 c.getClass();/hibernate不會執(zhí)行select語句c.getId();/hibernate不會執(zhí)行select語句 c.getAge();/該行hibernate會執(zhí)行select語句mit();se

33、s.close();只有延遲檢索會產(chǎn)生對象,立即檢索不會產(chǎn)生對象3.2.4.初始化延遲檢索中的3.2.5.區(qū)分類級別和關(guān)聯(lián)級別的檢索關(guān)聯(lián)級別的檢索:Customer c=(Customer)ses.load(Customer.class, 1);Set set=c.getOrders()/檢索Order對象的set集合在這個例子中ses.load(Customer.class, 1):查詢的主體表 c.getOrders():查詢客體表查詢客體表是否發(fā)生,以何種方式發(fā)生(立即檢索、延遲檢索和迫切左外連接檢索),就是關(guān)聯(lián)級別檢索通過set元素lazy屬性設(shè)定類級別的檢索:Customer c=(

34、Customer)ses.load(Customer.class, 1);ses的方法直接檢索Customer 對象, 對Customer 對象到底采用立即檢索還是延遲檢索方式,是通過class元素的lazy屬性設(shè)定的/初始化對象public void loadCustomertrueProxyInit()Sesses=sesFacoty.openSes(); Tranion tx=ses.begranion();/此時查詢到的c對象是一個對象Customer c=(Customer)ses.load(Customer.class, 1); System.out.prln(c.getClass

35、();/對象/判理對象是否被初始化 對集合對象也適用if(!Hibernate.isInitialized(c)System.out.prln(c.getClass();/對象System.out.prln(沒有被初始化);/初始化對象 hibernate執(zhí)行select查詢 Hibernate.initialize(c);mit();ses.close();.類級別檢索策略類級別可選的檢索策略包括立即檢索和延遲檢索, 默認(rèn)為延遲檢索類級別的檢索策略可以通過 元素的 lazy 屬性進(jìn)行設(shè)置如果程序加載一個對象的目的是為了它的屬性, 可以采取立即檢索. 如果程序加載一個持久化對象的

36、目的是僅僅為了獲得它的, 可以采用延遲檢索無論 元素的 lazy 屬性是 true 還是 false, Ses list() 方法在類級別總是使用立即檢索策略若 元素的 lazy 屬性為 true 或取默認(rèn)值, Ses的 get() 方法及 Query 的的 load() 方法不會執(zhí)行查詢類實例有如下特征:數(shù)據(jù)表的 SELECT 語句, 僅返回類對象的實例, 該由 Hibernate 在運行時采用 javassist 工具動態(tài)生成Hibernate 創(chuàng)建在應(yīng)用程序第一次類實例時, 僅初始化其 OID 屬性類實例的非OID 屬性時, Hibernate 會初始化類實例.關(guān)聯(lián)級別的檢

37、索策略在文件中, 用 元素來配置一對多關(guān)聯(lián)及多對多關(guān)聯(lián)關(guān)系. 元素有 lazyfetch 屬性。和lazy: 主要決定 orders 集合被初始化的時機(jī). 即到底是在加載 Customer 對象時就被初始化, 還是在程序orders 集合時被初始化fetch: 取值為 “select” 或 “subselect” 時, 決定初始化 orders 的查詢語句的形式;若取值為”join”, 則決定 orders 集合被初始化的時機(jī)若把 fetch 設(shè)置為 “join”, lazy 屬性將被忽略.1.一對多和多對多關(guān)聯(lián)的檢索策略(set) 元素的 lazy 和 fetch 屬性fetc

38、h(默認(rèn)值 select)Lazy(默認(rèn)值是 true)策略Joinfalse采用迫切左外聯(lián)接檢索。Jorue采用迫切左外聯(lián)接檢索。joinextra采用迫切左外聯(lián)接檢索。selectfalse采用立即檢索selectTrue采用延遲檢索selectextra采用延遲檢索c.getOrders().size()執(zhí)行 select count(id) from orderswhere customer_id =?for(Order o:set) o.getOrderNumber(); 將執(zhí)行:select customer_id , id,order_number ,price from ord

39、ers where customer_id=?subselectfalse/true/extra也分為 3 中情況嵌套子查詢(檢索多個 customer 對象時) Lazy 屬性決定檢索策略)select customer_id,order_numbrice from orders where customer_idin (select id from customers).2.延遲檢索和增強(qiáng)延遲檢索在延遲檢索(lazy 屬性值為 true) 集合屬性時, Hibernate 在以下情況下初始化集合類實例應(yīng)用程序第一次contains() 等方法集合屬性 : iterator()

40、, size(), isEmpty(),通過 Hibernate.initialize() 靜態(tài)方法顯式初始化增強(qiáng)延遲檢索(lazy 屬性為 extra): 與 lazy=“true”能進(jìn)一步延遲 Customer 對象的 orders 集合類似. 主要區(qū)別是增強(qiáng)延遲檢索策略實例的初始化時機(jī):當(dāng)程序第一次orders 屬性的 iterator() 方法時, 會導(dǎo)致 orders 集合類實例的初始化order 屬性的 size(), contains()和 isEmpty() 方法時, Hibernateselect 語句查詢必要的信息, 不當(dāng)程序第一次不會初始化 orders 集合類的實例,

41、僅通過特定的會檢索所有的 Order 對象.3.用帶子查詢的 select 語句整批量初始化 orders 集合(fetch 屬性為“subselect”) 元素的 fetch 屬性: 取值為 “select” 或 “subselect” 時, 決定初始化 orders 的查詢語句的形式;若取值為”join”, 則決定 orders 集合被初始化的時機(jī).默認(rèn)值為 select當(dāng) fetch 屬性為 “subselect” 時假定 Ses緩存中有 n 個 orders 集合類實例沒有被初始化, Hibernate 能夠通過帶子查詢的 select 語句, 來批量初始化 n 個 or

42、ders 集合類實例.4.迫切左外連接檢索(fetch 屬性值設(shè)為 “join”)fetch 屬性為 “join” 時:檢索 Customer 對象時, 會采用迫切左外連接(通過左外連接加載與檢索指定的對象關(guān)聯(lián)的對象)策略來檢索所有關(guān)聯(lián)的 Order 對象lazy 屬性將被忽略當(dāng)Query 的 list() 方或立即加載策略忽略文件中配置的迫切左外連接檢索策略, 而依舊采用延遲.多對一和一對一關(guān)聯(lián)的檢索策略元素也有一個lazy屬性和fetch屬性和 一樣, 元素也有一個lazy 屬性和fetch 屬性.若 fetch 屬性設(shè)為 join, 那么 lazy 屬性被忽略

43、迫切左外連接檢索策略的優(yōu)點在于比立即檢索策略使用的 SELECT 語句更少.無延遲檢索需要增強(qiáng)持久化類的字節(jié)碼才能實現(xiàn)Query 的 list 方略忽略文件配置的迫切左外連接檢索策略, 而采用延遲檢索策如果在關(guān)聯(lián)級別使用了延遲加載或立即加載檢索策略, 可以設(shè)定批量檢索的大小, 以幫助提高延遲檢索或立即檢索的運行性能.Hibernate 允許在應(yīng)用程序中覆蓋文件中設(shè)定的檢索策略.fetch(默認(rèn)值 select)Lazy(默認(rèn)值是 proxy)策略Joinfalse采用迫切左外聯(lián)接檢索。Joinproxy采用迫切左外聯(lián)接檢索。joinno-proxy采用迫切左外聯(lián)接檢索。selectfalse采

44、用立即檢索selectproxy如果對端 Customer.hbm.xml 中類級別的檢索是立即檢索則為立即檢索如果對端 Customer.hbm.xml 中類級別的檢索是延遲檢索則為延遲檢索selectno-proxy-(不研究)3.2.6.比較三種檢索策略3.3. 二級緩存3.3.1. Hibernate 的緩存緩存(Cache): 計算機(jī)領(lǐng)域非常通用的概念。它介于應(yīng)用程序和盤上的文件或者數(shù)據(jù)庫)之間,其作用是降低應(yīng)用程序直接讀寫性數(shù)據(jù)性數(shù)據(jù)源(如硬源的頻率,從而提高應(yīng)用的運行性能。緩存中的數(shù)據(jù)是數(shù)據(jù)是內(nèi)存源中數(shù)據(jù)的拷貝。緩存的物理介質(zhì)通常Hibernate 中提供了兩個級別的緩存第一級別

45、的緩存是 Ses級別的緩存,它是屬于事務(wù)范圍的緩存。這一級別的緩存由 hibernate 管理的,一般情況下無需進(jìn)行干預(yù)Ses第二級別的緩存是 SesFactory 級別的緩存,它是屬于進(jìn)程范圍的緩存Factory 的緩存可以分為兩類:內(nèi)置緩存: Hibernate 自帶的, 不可卸載. 通常在 Hibernate 的初始化階段, Hibernate會把元數(shù)據(jù)和預(yù)定義的 SQL 語句放到 SesFactory 的緩存中,元數(shù)據(jù)元數(shù)據(jù)推到是文件中數(shù)據(jù)的, 而預(yù)定義 SQL 語句時 Hibernate 根據(jù)出來的. 該內(nèi)置緩存是只讀的.外置緩存(二級緩存): 一個可配置的緩存插件. 在默認(rèn)情況下,

46、 SesFactory 不會啟用這個緩存插件. 外置緩存中的數(shù)據(jù)是數(shù)據(jù)庫數(shù)據(jù)的, 外置緩存的物理介質(zhì)檢索策略優(yōu)點缺點優(yōu)先考慮使用的場合立即檢索對應(yīng)用程序完全透明,不管對象處于持久化狀態(tài)還是游離狀態(tài),應(yīng)用程序都可以從一個對象導(dǎo)航到關(guān)聯(lián)的對象select 語句多可能會加載應(yīng)用程序不需要 的對象,浪費許多內(nèi)存空間。類級別應(yīng)用程序需要立即的對象使用了二級緩存延遲檢索由應(yīng)用程序決定需要加載哪些對象,可以避免執(zhí)行多余的 select 語句,以及避免加載應(yīng)用程序不需要 的對象。因此能提高檢索性能,并節(jié)省內(nèi)存空間。應(yīng)用程序如果希望游離狀態(tài)的 類實例,必須保證她在持久化狀態(tài)時已經(jīng)被初始化。一對多或者多對多關(guān)聯(lián)應(yīng)

47、用程序不需要立即 或者根本不會訪問的對象迫切左外 連接檢索對應(yīng)用程序完全透明,不管對象處于持久化狀態(tài)還是游離狀態(tài),都可從一個對象導(dǎo)航到另一個對象。使用了外連接,select 語句少可能會加載應(yīng)用程序不需要 的對象,浪費內(nèi)存。復(fù)雜的數(shù)據(jù)庫表連接也會影響檢索性能。多對一或一對一關(guān)聯(lián)需要立即的對象數(shù)據(jù)庫有良好的表連接性能??梢允莾?nèi)存或硬盤3.3.2. hibernate 二級緩存的結(jié)構(gòu)3.3.3. 理解二級緩存的并發(fā)策略兩個并發(fā)的事務(wù)同時持久層的緩存的相同數(shù)據(jù)時, 也有可能出現(xiàn)各類并發(fā)問題.二級緩存可以設(shè)定以下 4 種類型的并發(fā)級別策略, 每一種策略對應(yīng)一種事務(wù)只讀型(Read-Only):提供 S

48、erializable 數(shù)據(jù)級別, 對于從來不會被修改的數(shù)據(jù),可以采用這種策略讀寫型(Read-write): 提供 Read Commited 數(shù)據(jù)級別.對于經(jīng)常讀但是很少被修改的數(shù)據(jù), 可以采用這種類型, 因為它可以防止臟讀非嚴(yán)格讀寫(Nonstrict-read-write): 不保證緩存與數(shù)據(jù)庫中數(shù)據(jù)的一致性. 提供 Readmited 事務(wù)級別, 對于極少被修改, 而且允許臟讀的數(shù)據(jù), 可以采用這種策略事務(wù)型(Tranional): 僅在受管理環(huán)境下適用. 它提供了 Repeatable Read 事務(wù)隔離級別. 對于經(jīng)常讀但是很少被修改的數(shù)據(jù), 可以采用這種防止臟讀和不可重復(fù)讀類型

49、, 因為它可以適合放入二級緩存中的數(shù)據(jù):很少被修改不是很重要的數(shù)據(jù), 允許出現(xiàn)偶爾的并發(fā)問題不適合放入二級緩存中的數(shù)據(jù):經(jīng)常被修改財務(wù)數(shù)據(jù), 絕對不允許出現(xiàn)并發(fā)問題與其他應(yīng)用數(shù)據(jù)共享的數(shù)據(jù)3.3.4. 緩存提供的供應(yīng)商Hibernate 的二級緩存是進(jìn)程或集群范圍內(nèi)的緩存, 緩存中存放的是對象的散裝數(shù)據(jù)二級緩存是可配置的的插件, Hibernate 允許選用以下類型的緩存插件:EHCache: 可作為進(jìn)程范圍內(nèi)的緩存, 存放數(shù)據(jù)的物理介質(zhì)可以使內(nèi)存或硬盤, 對Hibernate 的查詢緩存提供了支持OpenSymphony OSCache:可作為進(jìn)程范圍內(nèi)的緩存, 存放數(shù)據(jù)的物理介質(zhì)可以使內(nèi)存

50、或硬盤, 提供了豐富的緩存數(shù)據(jù)過期策略, 對 Hibernate 的查詢緩存提供了支持 SwarmCache: 可作為集群范圍內(nèi)的緩存, 但不支持 Hibernate 的查詢緩存4JsCache:可作為集群范圍內(nèi)的緩存, 支持Hibernate 的查詢緩存空白代表不支持)種緩存插件支持的并發(fā)策略(x 代表支持,3.3.5. 配置 ehcache 緩存.配置步驟1, 拷貝 ehcache-1.5.0.jar 到當(dāng)前工程的 lib 目錄下2, 開啟二級緩存true 3, 指定緩存的供應(yīng)商.hibernate.cache.EhCacheProvider指定使用二級緩存的類方法一 在使用

51、類的*.hbm.xml 配置選擇需要使用二級緩存的持久化類, 設(shè)置它的二級緩存的并發(fā)4,策略, 元素的 cache 子元素表明 Hibernate 會緩存對象的簡單屬性, 但不會緩存集合屬性,若希望緩存集合屬性中的元素, 必須在 元素中加入 子元素方法二 在 hibernate.cfg.xml 文件中配置(建議)!-下面 -class-cache class=cn.c3p0.Order usage=read-write/配置 ehcache 默認(rèn)的配置文件 ehcache.xml(名字固定)(放在類路徑下)5,ehcache.xml 文件.ehcache.xml 文件配置說明:指

52、定一個目錄, 當(dāng) EHCache 把數(shù)據(jù)寫到硬盤上時, 將把數(shù)據(jù)寫到這個文件目錄下.默認(rèn)是 C:WINDOWSTemp: 設(shè)置緩存的默認(rèn)數(shù)據(jù)過期策略 設(shè)定具體名緩存的數(shù)據(jù)過期策略每個命名緩存代表一個緩存區(qū)域,每個緩存區(qū)域有各自的數(shù)據(jù)過期策略。命名緩存機(jī)制使得用戶能夠在每個類以及類的每個集合的粒度上設(shè)置數(shù)據(jù)過期策略。cache 元素的屬性name:設(shè)置緩存的名字,它的取值為類的全限定名或類的集合的名字maxElementsemory :設(shè)置基于內(nèi)存的緩存中可存放的對象最大數(shù)目eternal:設(shè)置對象是否為的,true 表示永不過期,此時將忽略 timeToIdleSeconds 和timeToL

53、iveSeconds 屬性; 默認(rèn)值是falsetimeToIdleSeconds:設(shè)置對象空閑最長時間,以秒為, 超過這個時間,對象過期。當(dāng)對象過期時,EHCache 會把它從緩存中清除。如果此值為 0,表示對象可以無限期地處于空閑狀態(tài)。timeToLiveSeconds:設(shè)置對象生存最長時間,超過這個時間,對象過期。如果此值為 0,表示對象可以無限期地存在于緩存中. 該屬性值必須大于或等于timeToIdleSeconds 屬性值overflowToDisk:設(shè)置基于內(nèi)存的緩存中的對象數(shù)目達(dá)到上限后,是否把溢出的對象寫到基于硬盤的緩存中diskPersistent 當(dāng) jvm 結(jié)束時是否持

54、久化對象 true false 默認(rèn)是 falsediskExpiryThreadervalSeconds 指定專門用于清除過期對象的間線程的輪詢時.測試需要引入兩個 jar 包在 sr下能找到.libconcurrentbackport-util-concurrent.jar.libcommons-logging.jar.1.測試二級緩存和散裝數(shù)據(jù)public void testCache() Sesses= sf.openSes();Tranion tx = ses.begranion();Customer customer = (Customer) ses.l

55、oad(Customer.class, 4); System.out.prln(customer.getAge();mit();ses.close();ses= sf.openSes();tx = ses.begranion();customer = (Customer) ses.load(Customer.class, 4); System.out.prln(customer.getAge();/ cn.c3p0.Customer1551b0 System.out.prln(customer);mit();ses.close();ses= sf.openSes();tx = ses.begr

56、anion();customer = (Customer) ses.load(Customer.class, 4); System.out.prln(customer.getAge();/ cn.c3p0.Customer1758500System.out.prln(customer); / 測試散列 是重組的對象mit();ses.close();.2.測試一級緩存更新數(shù)據(jù)會同步到二級緩存publicvoid testUpdate() SesTranses=sf.openSes();ion tx=ses.begranion();Customer customer=(Custom

57、er)ses.load(Customer.class, 4); System.out.prln(customer.getAge();customer.setAge(45);mit();ses.close();sestx=ses=sf.openSes();ion();.begrancustomer=(Customer)ses.load(Customer.class, 4);System.out.prln(customer.getAge(); mit();ses.close();/4.3.測試二級緩存的數(shù)據(jù)存放到臨時目錄3.3.6. 時間戳緩存區(qū)域默認(rèn)的查詢緩存區(qū)域以及用戶自定義的

58、查詢緩存區(qū)域都用于存放查詢結(jié)果。而時間戳緩存區(qū)域存放了對與查詢結(jié)果相關(guān)的表進(jìn)行、更新或刪除操作的時間戳。 Hibernate 通過時間戳緩存區(qū)域來判斷被緩存的查詢結(jié)果是否過期。所以,當(dāng)應(yīng)用程序?qū)?shù)據(jù)庫的相關(guān)數(shù)據(jù)做了修改,Hibernate 會自動刷新緩存的查詢結(jié)果。Hibernate 提供了和查詢相關(guān)的緩存區(qū)域:時間戳緩存區(qū)域:.hibernate.cahce.UpdateTimestCache, 更新或刪除操作的時間戳.時間戳緩存區(qū)域存放了對于查詢結(jié)果相關(guān)的表進(jìn)行Hibernate 通過時間戳緩存區(qū)域來判斷被緩存的查詢結(jié)果是否過期, 其運行過程如下:T1 時刻執(zhí)行查詢操作, 把查詢結(jié)果存放在

59、 QueryCache 區(qū)域,為 T1T2 時刻對查詢結(jié)果相關(guān)的表進(jìn)行更新操作, Hibernate 把 T2 時刻存放在該區(qū)域的時間戳UpdateTimestCache 區(qū)域.T3 時 刻 執(zhí) 行 查 詢 結(jié) 果 前 , 先比較QueryCache 區(qū)域的時間戳和 UpdateTimestCache 區(qū)域的時間戳, 若 T2 T1, 那么就丟棄原先存放在QueryCache 區(qū)域的查詢結(jié)果, 重新到數(shù)據(jù)庫中查詢數(shù)據(jù), 再把結(jié)果存放到QueryCache 區(qū)域; 若 T2 T1, 直接從 QueryCache 中獲得查詢結(jié)果測試時間戳緩存區(qū)域/測試緩存溢出存放到臨時目錄 Testpublicvoid testowerFlow() Sesses=sf.openSes();Tranion tx=ses.begranion();Query qu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論