《輕量級Java EE程序設計及實踐》課件第6章 Hibernate核心技能_第1頁
《輕量級Java EE程序設計及實踐》課件第6章 Hibernate核心技能_第2頁
《輕量級Java EE程序設計及實踐》課件第6章 Hibernate核心技能_第3頁
《輕量級Java EE程序設計及實踐》課件第6章 Hibernate核心技能_第4頁
《輕量級Java EE程序設計及實踐》課件第6章 Hibernate核心技能_第5頁
已閱讀5頁,還剩32頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

privateCustomercustomer;

省略getter和setter方法

...}<hibernate-mappingpackage="com.dh.ch05.pojos"> <classname="Order"table="ORDER"> <idname="id"column="ID"> <generatorclass="native"/> </id> <!--訂單編號--> <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對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關聯關系-->

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

-7-基于外鍵的單向1對1關系publicclassIdCard{ /*主鍵ID*/ privateIntegerid; /*身份證編號*/ privateStringcardNo;

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

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

<!--基于外鍵的1-1關聯-->

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

cascade="all“column="IDCARD_ID"

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

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

<!--映射one-to-one關聯關系-->

<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對應關系-->

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

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

-9-單向N對N關系publicclassProduct{ /*主鍵*/ privateIntegerid; /*商品產品名*/ privateStringname; /*商品產品價格*/ privateDoubleprice; /*商品產品描述*/ 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{

省略

/*產品集合*/ 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對N關系<!--配置多對多關聯--><setname="orders"table="ORDERITEM"> <keycolumn="PRODUCT_ID"/> <many-to-manyclass="Order"column="ORDER_ID"/></set>示例6.6

-11-拆分N對N為兩個1對NpublicclassOrderItem{ privateIntegerid; /*訂單屬性*/ privateOrderorder; /*商品產品屬性*/ privateProductproduct; /*商品產品數量*/ privateIntegerquantity; /*購買價格*/ privateDoublepurchasePrice;省略}<classname="OrderItem"table="ORDERITEM"> <idname="id"column="ID"> <generatorclass="native"/> </id> <!--OrderItem與Order是1-N關系--> <many-to-onename="order"class="Order"

column="ORDER_ID"/> <!--OrderItem與Product是1-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個Customer對象*/for(inti=0;i<1000000;i++){ Customercustomer=newCustomer(); //保存對象

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

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

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

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

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

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

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); //當count為20的倍數時,將更新的結果從Session中flush到數據庫

if(count%20==0){ //同步持久化對象與數據庫

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

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

-14-Hibernate檢索方式檢索方式描述導航對象圖檢索方式根據已加載的對象,利用對象之間關聯關系,導航到其他對象。例如,對于已經加載的Customer對象,通過調用該對象的getOrders().iterator()方法就可以導航到某一個Order對象OID檢索方式按照對象的OID來檢索對象。可以使用Session的load()或get()方法。例如,想要檢索OID為1的Customer對象,如果數據庫中存在,就可以通過load(Customer.class,1)檢索到該對象。HQL檢索方式使用HQL(HibernateQueryLanguage)查詢語言來檢索對象。Hibernate中提供了Query接口,該接口是HQL查詢接口,能夠執行各種復雜的HQL查詢語句。詳見6.4小節。QBC檢索方式使用QBC(QueryByCriteria)API來檢索對象。該API提供了更加面向對象的接口,用于各種復雜的查詢。詳見6.5小節。本地SQL檢索方式使用本地數據庫的SQL查詢語句。Hibernate負責把檢索到的JDBCResultSet結果集映射為持久化對象圖。-15-HQL檢索使用HQL查詢可按照如下步驟進行:獲取Hibernate的Session對象編寫HQL查詢語句以HQL作為參數,調用Session對象的createQuery()方法,創建Query對象如果HQL語句中包含參數,調用Query對象的setXXX()方法為參數賦值調用Query對象的list()等方法得到查詢結果-16-QBC檢索QBC檢索也稱為條件查詢,是完全面向對象的數據檢索方式,主要通過下面三個類完成:Criteria:代表一次查詢Criterion:代表一個查詢條件Restrictions:產生查詢條件的工具類執行條件查詢的步驟如下:獲取Hibernate的Session對象并以某類的Class對象作為參數調用Session對象的createCriteria()方法,創建Criteria對象通過調用Criteria對象的add()方法,增加Criterion查詢條件執行Criteria的list()等方法得到查詢結果

-17-使用別名通過HQL檢索一個類的實例時,如果在查詢語句的其他地方需要引用該類,應該為其指定一個別名其中,as關鍵字用于設定別名,也可以將as關鍵字省略fromCustomerascwherec.realName='zhangsan'fromCustomercwherec.realName='zhangsan'-18-排序HQLCriteriaStringhql="fromCustomercorderbyc.userNamedesc";Criteriacritera=session.createCriteria(Customer.class);critera.addOrder(org.hibernate.criterion.Order.asc("userName"));-19-分頁HQLCriteriaQueryquery=session.createQuery(hql);//設置滿足條件的第一條記錄的位置query.setFirstResult((pageNo-1)*perPageNum);//限定查詢返回的記錄的總數query.setMaxResults(perPageNum);//返回滿足條件的記錄List<Customer>list=query.list();Criteriacriteria=session.createCriteria(Customer.class);//設置開始條數criteria.setFirstResult((pageNo-1)*perPageNum);//限定查詢返回的記錄的總數criteria.setMaxResults(perPageNum);//返回滿足條件的記錄List<Customer>list=criteria.list();-20-檢索一條記錄HQLCriteriaStringhql="fromCustomercorderbyc.userNamedesc";//查詢獲取Customer對象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-設定查詢條件-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-設定查詢條件-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-帶參數的HQLStringhql="fromCustomerascwherec.realName=:realname";Queryquery=session.createQuery(hql);//按照參數名字進行綁定query.setString("realname",name);Stringhql="fromCustomerascwherec.realName=?";Queryquery=session.createQuery(hql);//按照參數位置進行綁定query.setString(0,name);-24-連接查詢HQL同SQL一樣支持各種常見的連接查詢,例如內連接、外連接等連接類型HQL語法適用條件內連接innerjoin或join適用于有關聯的持久化類,并且在映射文件中對這種關聯關系作了映射預先抓取內連接innerjoinfetch或joinfetch左外連接leftouterjoin或leftjoin預先抓取左外連接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());}必須有對應的構造方法

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

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

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

-26-分組與統計-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-分組與統計-Criteria使用Projection接口實現以Criteria方式進行分組與統計查詢方法名描述avg(StringpropertyName)對某個屬性求平均值max(StringpropertyName)對某個屬性求最大值min(StringpropertyName)對某個屬性就最小值sum(StringpropertyName)對某個屬性求和count(StringpropertyName)根據某個屬性來統計記錄數,和count(propertyName)類似rowCount()統計行數,與count(*)類似countDistinct(StringpropertyName)不重復的統計記錄數,與count(distinctpropertyName)類似groupProperty(Stringpropame)根據特定屬性分組,與groupbyproname類似projectionList()返回一個ProjectionList對象數組,代表投影列表property(StringpropertyName)把某個屬性加入到投影查詢中-28-HQL動態查詢StringBufferbuffer=newStringBuffer();//生成基礎SQLbuffer.append("fromCustomercwhere1=1");//如果name滿足條件,則加入語句中if(name!=null) buffer.append("andc.userNamelike:name");//如果age滿足條件,則加入語句中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動態查詢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 //根據樣本對象創建Example對象

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

.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(); //無關子查詢

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

評論

0/150

提交評論