《輕量級(jí)Java EE程序設(shè)計(jì)及實(shí)踐》課件第6章 Hibernate核心技能_第1頁(yè)
《輕量級(jí)Java EE程序設(shè)計(jì)及實(shí)踐》課件第6章 Hibernate核心技能_第2頁(yè)
《輕量級(jí)Java EE程序設(shè)計(jì)及實(shí)踐》課件第6章 Hibernate核心技能_第3頁(yè)
《輕量級(jí)Java EE程序設(shè)計(jì)及實(shí)踐》課件第6章 Hibernate核心技能_第4頁(yè)
《輕量級(jí)Java EE程序設(shè)計(jì)及實(shí)踐》課件第6章 Hibernate核心技能_第5頁(yè)
已閱讀5頁(yè),還剩32頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

-1-掌握Hibernate中持久化類的各種關(guān)聯(lián)關(guān)系掌握Hibernate的批量處理掌握Query接口的核心方法和使用掌握利用HQL進(jìn)行的各種查詢技巧掌握Criteria接口的核心方法和使用掌握利用Criteria進(jìn)行的各種查詢技巧掌握Restrictions使用的方法掌握使用DetachedCriteria離線查詢的技巧掌握Hibernate中的事務(wù)處理方法目標(biāo)-2-Hibernate關(guān)聯(lián)關(guān)系關(guān)聯(lián)關(guān)系可分為下面幾種:一對(duì)一關(guān)聯(lián)(1-1)一對(duì)多關(guān)聯(lián)(1-N)多對(duì)多關(guān)聯(lián)(N-N)按照訪問關(guān)聯(lián)關(guān)系的方向性,又可以分為:?jiǎn)蜗蜿P(guān)聯(lián):只需要單向訪問關(guān)聯(lián)端雙向關(guān)聯(lián):關(guān)聯(lián)的兩端可以互相訪問綜上所述:?jiǎn)蜗?-1單向1-N單向N-1單向N-N雙向1-1雙向1-N雙向N-N-3-單向N對(duì)1關(guān)系單向N-1關(guān)聯(lián)和關(guān)系數(shù)據(jù)庫(kù)中的外鍵參照關(guān)系最為相似publicclassOrderimplementsSerializable{ /*主鍵Id*/ privateIntegerid; /*訂單編號(hào)*/ privateStringorderNo; /*下單日期*/ privateDatedate; /*總金額*/ privateDoubletotal; /*關(guān)聯(lián)客戶*/

privateCustomercustomer;

省略getter和setter方法

...}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Order"table="ORDER"> <idname="id"column="ID"> <generatorclass="native"/> </id> <!--訂單編號(hào)--> <propertyname="orderNo" column="ORDERNO"type="string"/> <!--下單日期:yyyy-MM-ddHH:MM:SS--> <propertyname="date" column="ORDERDATE"type="timestamp"/> <!--總金額--> <propertyname="total"column="TOTAL"type="double"/> <!--單向N-1-->

<many-to-onename="customer" column="CUSTOMER_ID"class="Customer"/> </class></hibernate-mapping>示例6.1

-4-單向1對(duì)N關(guān)系publicclassCustomerimplementsSerializable{ /*訂單集合orders*/

privateSet<Order>orders=newHashSet<Order>(0); publicSet<Order>getOrders(){ returnorders; } publicvoidsetOrders(Set<Order>orders){ this.orders=orders; }其他屬性省略}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Customer"table="CUSTOMER">

<!--1-N關(guān)聯(lián)關(guān)系-->

<setname="orders"> <keycolumn="CUSTOMER_ID"/> <one-to-manyclass="Order"/> </set> </class></hibernate-mapping>-5-雙向1對(duì)N關(guān)系雙向1-N關(guān)聯(lián)就是1-N與N-1單向關(guān)聯(lián)的整合雙向1-N建立了1端和N端的雙向關(guān)聯(lián)關(guān)系,既可以從1端導(dǎo)航到N端,也可以從N端導(dǎo)航到1端可以從通過客戶直接訪問其所擁有的所有訂單,也可以通過某個(gè)訂單訪問該訂單所屬的客戶對(duì)象-6-級(jí)聯(lián)關(guān)系持久對(duì)象進(jìn)行保存、更新和刪除等操作時(shí),有時(shí)需要被關(guān)聯(lián)的對(duì)象也要執(zhí)行相應(yīng)的操作,這可以通過使用Hibernate的級(jí)聯(lián)(cascade)功能完成屬性值描述none默認(rèn)值,表示關(guān)聯(lián)對(duì)象之間無(wú)級(jí)聯(lián)操作save-update表示主動(dòng)方對(duì)象在調(diào)用save(),update()和saveOrUpdate()方法時(shí)對(duì)被關(guān)聯(lián)對(duì)象執(zhí)行保存或更新操作delete表示主動(dòng)方對(duì)象在調(diào)用delete()方法時(shí)對(duì)被關(guān)聯(lián)對(duì)象執(zhí)行刪除操作delete-orphan用在1-N關(guān)聯(lián)中,表示主動(dòng)方對(duì)象調(diào)用delete()方法時(shí)刪除不被任何一個(gè)關(guān)聯(lián)對(duì)象所引用的關(guān)聯(lián)對(duì)象,多用于父子關(guān)聯(lián)對(duì)象中all等價(jià)于save-update和delete的聯(lián)合使用示例6.2

-7-基于外鍵的單向1對(duì)1關(guān)系publicclassIdCard{ /*主鍵ID*/ privateIntegerid; /*身份證編號(hào)*/ privateStringcardNo;

省略}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="IdCard"table="IDCARD"> <!--主鍵--> <idname="id"column="ID"> <generatorclass="native"/> </id> <!--身份證編號(hào)--> <propertyname="cardNo" column="CARDNO"type="string"/> </class></hibernate-mapping>publicclassCustomerimplementsSerializable{省略

/*身份證對(duì)象*/ privateIdCardidCard;……省略getter/setter方法}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Customer"table="CUSTOMER"> <idname="id"column="ID"> <generatorclass="native"/> </id>省略

<!--基于外鍵的1-1關(guān)聯(lián)-->

<many-to-onename="idCard"class="IdCard"

cascade="all“column="IDCARD_ID"

unique="true"/> </class></hibernate-mapping>示例6.3

-8-基于主鍵的雙向1對(duì)1關(guān)系<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Customer"table="CUSTOMER">

<!--映射one-to-one關(guān)聯(lián)關(guān)系-->

<one-to-onename="idCard"class="IdCard"cascade="all"/> </class></hibernate-mapping><hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="IdCard"table="IDCARD"> <idname="id"column="ID"> <generatorclass="foreign"> <paramname="property"> customer </param> </generator> </id> <!--建立了one-to-one對(duì)應(yīng)關(guān)系-->

<one-to-onename="customer"class="Customer"

constrained="true"/> </class></hibernate-mapping>示例6.4

-9-單向N對(duì)N關(guān)系publicclassProduct{ /*主鍵*/ privateIntegerid; /*商品產(chǎn)品名*/ privateStringname; /*商品產(chǎn)品價(jià)格*/ privateDoubleprice; /*商品產(chǎn)品描述*/ privateStringdescription;省略}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Product"table="PRODUCT"> <idname="id"column="ID"> <generatorclass="native"/> </id> <propertyname="name"column="NAME"type="string" not-null="true"/> <propertyname="price"column="PRICE"type="double" not-null="true"/> <propertyname="description" column="DESCRIPTION"type="string"/> </class></hibernate-mapping>publicclassOrder{

省略

/*產(chǎn)品集合*/ privateSet<Product>products;省略}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Order"table="ORDERS">

省略

<setname="products"table="ORDERITEM"> <keycolumn="ORDER_ID"/> <many-to-manyclass="Product"

column="PRODUCT__ID"/> </set> </class></hibernate-mapping>示例6.5

-10-雙向N對(duì)N關(guān)系<!--配置多對(duì)多關(guān)聯(lián)--><setname="orders"table="ORDERITEM"> <keycolumn="PRODUCT_ID"/> <many-to-manyclass="Order"column="ORDER_ID"/></set>示例6.6

-11-拆分N對(duì)N為兩個(gè)1對(duì)NpublicclassOrderItem{ privateIntegerid; /*訂單屬性*/ privateOrderorder; /*商品產(chǎn)品屬性*/ privateProductproduct; /*商品產(chǎn)品數(shù)量*/ privateIntegerquantity; /*購(gòu)買價(jià)格*/ privateDoublepurchasePrice;省略}<classname="OrderItem"table="ORDERITEM"> <idname="id"column="ID"> <generatorclass="native"/> </id> <!--OrderItem與Order是1-N關(guān)系--> <many-to-onename="order"class="Order"

column="ORDER_ID"/> <!--OrderItem與Product是1-N關(guān)系--> <many-to-onename="product"class="Product“ column="PRODUCT_ID"/> <propertyname="quantity"column="QUANTITY" type="integer"/> <propertyname="purchasePrice" column="PURCHASEPRICE"type="double"/></class><hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Order"table="ORDERS">省略

<setname="orderitems"cascade="save-update"

inverse="true“table="ORDERITEM"> <keycolumn="ORDER_ID"/> <one-to-manyclass="OrderItem"/> </set> </class></hibernate-mapping><hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Product"table="PRODUCT">省略

<setname="orderitems"table="ORDERITEM"inverse="true"> <keycolumn="PRODUCT_ID"/> <one-to-manyclass="OrderItem"/> </set> </class></hibernate-mapping>示例6.7

-12-批量插入Transactiontrans=session.beginTransaction();/*保存1000000個(gè)Customer對(duì)象*/for(inti=0;i<1000000;i++){ Customercustomer=newCustomer(); //保存對(duì)象

session.save(customer);}//提交事務(wù)mit();for(inti=0;i<1000000;i++){ //創(chuàng)建Customer對(duì)象

Customercustomer=newCustomer(); customer.setUserName("name"+(i+1)); customer.setPassword("123456"); //保存對(duì)象

session.save(customer); if(i%20==0){ //清理緩存

session.flush(); //清空緩存

session.clear(); //提交事務(wù)

mit(); //重新開始事務(wù)

trans=session.beginTransaction(); }}示例6.8

-13-批量更新ScrollableResultscustomers =session.createQuery("fromCustomer").scroll();intcount=0;while(customers.next()){ Customercustomer=(Customer)customers.get(0); customer.setUserName("username"+count); //當(dāng)count為20的倍數(shù)時(shí),將更新的結(jié)果從Session中flush到數(shù)據(jù)庫(kù)

if(count%20==0){ //同步持久化對(duì)象與數(shù)據(jù)庫(kù)

session.flush(); //清空緩存

session.clear(); mit(); trans=session.beginTransaction(); } count++;}//提交事務(wù)mit();Transactiontrans=session.beginTransaction();//定義HQL語(yǔ)句Stringhql="updateCustomersetname=:name";//獲取HQLQuery對(duì)象Queryquery=session.createQuery(hql);//進(jìn)行參數(shù)綁定query.setString("name","username");//執(zhí)行更新query.executeUpdate();//提交事務(wù)mit();示例6.9

-14-Hibernate檢索方式檢索方式描述導(dǎo)航對(duì)象圖檢索方式根據(jù)已加載的對(duì)象,利用對(duì)象之間關(guān)聯(lián)關(guān)系,導(dǎo)航到其他對(duì)象。例如,對(duì)于已經(jīng)加載的Customer對(duì)象,通過調(diào)用該對(duì)象的getOrders().iterator()方法就可以導(dǎo)航到某一個(gè)Order對(duì)象OID檢索方式按照對(duì)象的OID來檢索對(duì)象。可以使用Session的load()或get()方法。例如,想要檢索OID為1的Customer對(duì)象,如果數(shù)據(jù)庫(kù)中存在,就可以通過load(Customer.class,1)檢索到該對(duì)象。HQL檢索方式使用HQL(HibernateQueryLanguage)查詢語(yǔ)言來檢索對(duì)象。Hibernate中提供了Query接口,該接口是HQL查詢接口,能夠執(zhí)行各種復(fù)雜的HQL查詢語(yǔ)句。詳見6.4小節(jié)。QBC檢索方式使用QBC(QueryByCriteria)API來檢索對(duì)象。該API提供了更加面向?qū)ο蟮慕涌冢糜诟鞣N復(fù)雜的查詢。詳見6.5小節(jié)。本地SQL檢索方式使用本地?cái)?shù)據(jù)庫(kù)的SQL查詢語(yǔ)句。Hibernate負(fù)責(zé)把檢索到的JDBCResultSet結(jié)果集映射為持久化對(duì)象圖。-15-HQL檢索使用HQL查詢可按照如下步驟進(jìn)行:獲取Hibernate的Session對(duì)象編寫HQL查詢語(yǔ)句以HQL作為參數(shù),調(diào)用Session對(duì)象的createQuery()方法,創(chuàng)建Query對(duì)象如果HQL語(yǔ)句中包含參數(shù),調(diào)用Query對(duì)象的setXXX()方法為參數(shù)賦值調(diào)用Query對(duì)象的list()等方法得到查詢結(jié)果-16-QBC檢索QBC檢索也稱為條件查詢,是完全面向?qū)ο蟮臄?shù)據(jù)檢索方式,主要通過下面三個(gè)類完成:Criteria:代表一次查詢Criterion:代表一個(gè)查詢條件Restrictions:產(chǎn)生查詢條件的工具類執(zhí)行條件查詢的步驟如下:獲取Hibernate的Session對(duì)象并以某類的Class對(duì)象作為參數(shù)調(diào)用Session對(duì)象的createCriteria()方法,創(chuàng)建Criteria對(duì)象通過調(diào)用Criteria對(duì)象的add()方法,增加Criterion查詢條件執(zhí)行Criteria的list()等方法得到查詢結(jié)果

-17-使用別名通過HQL檢索一個(gè)類的實(shí)例時(shí),如果在查詢語(yǔ)句的其他地方需要引用該類,應(yīng)該為其指定一個(gè)別名其中,as關(guān)鍵字用于設(shè)定別名,也可以將as關(guān)鍵字省略fromCustomerascwherec.realName='zhangsan'fromCustomercwherec.realName='zhangsan'-18-排序HQLCriteriaStringhql="fromCustomercorderbyc.userNamedesc";Criteriacritera=session.createCriteria(Customer.class);critera.addOrder(org.hibernate.criterion.Order.asc("userName"));-19-分頁(yè)HQLCriteriaQueryquery=session.createQuery(hql);//設(shè)置滿足條件的第一條記錄的位置query.setFirstResult((pageNo-1)*perPageNum);//限定查詢返回的記錄的總數(shù)query.setMaxResults(perPageNum);//返回滿足條件的記錄List<Customer>list=query.list();Criteriacriteria=session.createCriteria(Customer.class);//設(shè)置開始條數(shù)criteria.setFirstResult((pageNo-1)*perPageNum);//限定查詢返回的記錄的總數(shù)criteria.setMaxResults(perPageNum);//返回滿足條件的記錄List<Customer>list=criteria.list();-20-檢索一條記錄HQLCriteriaStringhql="fromCustomercorderbyc.userNamedesc";//查詢獲取Customer對(duì)象Customercustomer=(Customer)session.createQuery(hql)

.setMaxResults(1).uniqueResult();Customercustomer=(Customer)session .createQuery("fromCustomercwherec.id=1") .uniqueResult();

Customercustomer=(Customer)session .createCriteria(Customer.class) .setMaxResults(1).uniqueResult();-21-設(shè)定查詢條件-HQLHQLfromCustomercwherec.age=18fromCustomercwherec.age<>18fromCustomercwherec.realNameisnullfromCustomercwherelower(c.userName)='張三'fromCustomercwherec.realNamenotin('張三','李四','王五')fromCustomercwherec.agenotbetween18and20fromCustomercwherec.realNamelike'張%'fromCustomercwherec.userNamelike'z___'fromCustomercwherec.userNamelike'z%'andlength(password)>6fromCustomercwherec.userNamelike'z%'or(c.agenotbetween20and30)-22-設(shè)定查詢條件-CriteriaCriteriacriteria.add(Restrictions.ge("age",age));criteria.add(Restrictions.isNotNull("realName"));criteria.add(Restrictions.eq("userName",userName).ignoreCase());criteria.add(Restrictions.in("realName",names));criteria.add(Restrictions.between("age",18,20));criteria.add(Restrictions.like("userName","z",MatchMode.START));criteria.add(Restrictions.like("userName","zh",MatchMode.ANYWHERE));criteria.add(Restrictions.like("userName","z%"));criteria.add(Restrictions.like("userName","%n"));criteria.add(Restrictions.or(Restrictions.like("userName","z%"), Restrictions.like("userName","%n")));-23-帶參數(shù)的HQLStringhql="fromCustomerascwherec.realName=:realname";Queryquery=session.createQuery(hql);//按照參數(shù)名字進(jìn)行綁定query.setString("realname",name);Stringhql="fromCustomerascwherec.realName=?";Queryquery=session.createQuery(hql);//按照參數(shù)位置進(jìn)行綁定query.setString(0,name);-24-連接查詢HQL同SQL一樣支持各種常見的連接查詢,例如內(nèi)連接、外連接等連接類型HQL語(yǔ)法適用條件內(nèi)連接innerjoin或join適用于有關(guān)聯(lián)的持久化類,并且在映射文件中對(duì)這種關(guān)聯(lián)關(guān)系作了映射預(yù)先抓取內(nèi)連接innerjoinfetch或joinfetch左外連接leftouterjoin或leftjoin預(yù)先抓取左外連接leftouterjoinfetch或leftjoinfetch右外連接rightouterjoin或rightjoinfromCustomercinnerjoinc.ordersowherec.userNamelike'張%'fromCustomercinnerjoinfetchc.ordersowherec.userNamelike'張%'fromCustomercleftjoinc.ordersowherec.age>?fromCustomercleftjoinfetchc.orderswherec.age>?-25-投影Stringhql="selectc.id,c.userNamefromCustomerc";Queryquery=session.createQuery(hql);List<Object[]>list=query.list();for(Object[]objs:list){ System.out.println(objs[0]+""+objs[1]);}Stringhql="selectnewCustomer(c.id,c.userName)

fromCustomerc";Queryquery=session.createQuery(hql);List<Customer>list=query.list();for(Customerc:list){ System.out.println(c.getId()+""+c.getUserName());}必須有對(duì)應(yīng)的構(gòu)造方法

Stringhql="selectnewCustomerRow(c.id,c.userName)

fromCustomerc";Stringhql="selectnewmap(c.id,c.userName)

fromCustomerc";不能得到完整的對(duì)象,只能得到Object[]

-26-分組與統(tǒng)計(jì)-HQLHQLselectcount(c.id)fromCustomercselectavg(c.age)fromCustomercselectmax(c.age),min(c.age)fromCustomercselectc.userName,count(o)fromCustomercleftjoinc.orders ogroupbyc.id

selectc.userName,count(o)fromCustomerc leftjoinc.orderso

groupbyc.id

havingcount(o)>=1

-27-分組與統(tǒng)計(jì)-Criteria使用Projection接口實(shí)現(xiàn)以Criteria方式進(jìn)行分組與統(tǒng)計(jì)查詢方法名描述avg(StringpropertyName)對(duì)某個(gè)屬性求平均值max(StringpropertyName)對(duì)某個(gè)屬性求最大值min(StringpropertyName)對(duì)某個(gè)屬性就最小值sum(StringpropertyName)對(duì)某個(gè)屬性求和count(StringpropertyName)根據(jù)某個(gè)屬性來統(tǒng)計(jì)記錄數(shù),和count(propertyName)類似rowCount()統(tǒng)計(jì)行數(shù),與count(*)類似countDistinct(StringpropertyName)不重復(fù)的統(tǒng)計(jì)記錄數(shù),與count(distinctpropertyName)類似groupProperty(Stringpropame)根據(jù)特定屬性分組,與groupbyproname類似projectionList()返回一個(gè)ProjectionList對(duì)象數(shù)組,代表投影列表property(StringpropertyName)把某個(gè)屬性加入到投影查詢中-28-HQL動(dòng)態(tài)查詢StringBufferbuffer=newStringBuffer();//生成基礎(chǔ)SQLbuffer.append("fromCustomercwhere1=1");//如果name滿足條件,則加入語(yǔ)句中if(name!=null) buffer.append("andc.userNamelike:name");//如果age滿足條件,則加入語(yǔ)句中if(age!=null&&age!=0) buffer.append("andc.age=:age");Queryquery=session.createQuery(buffer.toString());if(name!=null) query.setString("name","%"+name.toLowerCase()+"%");if(age!=null&&age!=0) query.setInteger("age",age);returnquery.list();-29-Criteria動(dòng)態(tài)查詢Criteriacriteria=session.createCriteria(Customer.class);if(name!=null){ criteria.add(Restrictions.ilike("userName", name, MatchMode.ANYWHERE));}if(age!=null&&age!=0){ criteria.add(Restrictions.eq("age",age));}returncriteria.list();-30-QBE查詢Exampleexample=Example //根據(jù)樣本對(duì)象創(chuàng)建Example對(duì)象

.create(customer) //對(duì)所有String類型的字段進(jìn)行模糊匹配

.enableLike(MatchMode.ANYWHERE) //不把為空的字段加入where子句中

.excludeNone() //不把值為0的字段加入where子句中

.excludeZeroes() //忽略所有String類型字段的大小寫

.ignoreCase();Criteriacriteria=session.createCriteria(Customer.class);criteria.add(example);returncriteria.list();-31-DetachedCriteria離線查詢-32-HQL子查詢–單行子查詢publicstaticvoidfindCustomersBySubQuerys(){ Sessionsession=HibernateUtils.getSession(); //無(wú)關(guān)子查詢

Stringhql="fromCustomercwherec.age= (selectc1.agefromCustomerc1 wherec1.userName=:userName) andc.userName!=:userName"; Queryquery=session.createQuery(hql); query.setString("userName","zhangsan"); List<Customer>list=query.list(); for(Customercustomer:list){ System.out.println(customer.getUserName()); }}-33-HQL子查詢–多行子查詢fromCustomercwhere100>all(sel

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論