




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
-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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度瓷砖美缝行业人才培养与输送合同
- 二零二五年度工业厂房装修合同终止书
- 二零二五年度个人租赁房屋押金管理合同协议
- 旅行社装修合同验收要点
- 农家烧酒售卖合同范例
- 借房子正规合同范例
- 中空玻璃销售合同范例
- 个人庭院出租合同范例
- 代工附加协议合同范例
- 主播月合同范例
- 大班科学《灯的故事》PPT优质课件
- 保健品概念及分类
- 水土保持监理实施细则
- 打印版80个常见象形字(一年级必备)课件
- 自体血液回收机使用(精京3000P型)课件
- 非法捕捞水产品罪
- 中铝中州矿业有限公司禹州市方山铝土矿矿山地质环境保护和土地复垦方案
- 浆渣自分离立式磨浆机设计-毕业设计
- 《胸部疾病的CT诊断》
- 重庆2023年重庆鈊渝金融租赁股份有限公司(筹)招聘上岸提分题库3套【500题带答案含详解】
- JJG 596-1999电子式电能表
评论
0/150
提交评论