jpql查询Word下载.docx

上传人:b****2 文档编号:970773 上传时间:2023-04-29 格式:DOCX 页数:17 大小:20.79KB
下载 相关 举报
jpql查询Word下载.docx_第1页
第1页 / 共17页
jpql查询Word下载.docx_第2页
第2页 / 共17页
jpql查询Word下载.docx_第3页
第3页 / 共17页
jpql查询Word下载.docx_第4页
第4页 / 共17页
jpql查询Word下载.docx_第5页
第5页 / 共17页
jpql查询Word下载.docx_第6页
第6页 / 共17页
jpql查询Word下载.docx_第7页
第7页 / 共17页
jpql查询Word下载.docx_第8页
第8页 / 共17页
jpql查询Word下载.docx_第9页
第9页 / 共17页
jpql查询Word下载.docx_第10页
第10页 / 共17页
jpql查询Word下载.docx_第11页
第11页 / 共17页
jpql查询Word下载.docx_第12页
第12页 / 共17页
jpql查询Word下载.docx_第13页
第13页 / 共17页
jpql查询Word下载.docx_第14页
第14页 / 共17页
jpql查询Word下载.docx_第15页
第15页 / 共17页
jpql查询Word下载.docx_第16页
第16页 / 共17页
jpql查询Word下载.docx_第17页
第17页 / 共17页
亲,该文档总共17页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

jpql查询Word下载.docx

《jpql查询Word下载.docx》由会员分享,可在线阅读,更多相关《jpql查询Word下载.docx(17页珍藏版)》请在冰点文库上搜索。

jpql查询Word下载.docx

//命名参数查询时使用,参数类型为java.util.Date

QuerysetParameter(Stringname,java.util.Datevalue,TemporalTypetemporalType);

//命名参数查询时使用,参数类型为java.util.Calendar

QuerysetParameter(Stringname,Calendarvalue,TemporalTypetemporalType);

//位置参数查询时使用,参数类型为java.util.Date

QuerysetParameter(intposition,Datevalue,TemporalTypetemporalType);

//位置参数查询时使用,参数类型为java.util.Calendar

QuerysetParameter(intposition,Calendarvalue,TemporalTypetemporalType);

}

因为一个Date或Calendar对象能够描述一个真实的日期、时间或时间戳.所以我们需要告诉Query对象怎么使用这些参数,我们把javax.persistence.TemporalType作为参数传递进setParameter方法,告诉查询接口在转换java.util.Date或java.util.Calendar参数到本地SQL时使用什么数据库类型。

下面通过实例来学习JPQL语句,例子的entityBean有Person,Order,OrderItem,他们之间的关系是:

一个Person有多个Order,一个Order有多个OrderItem。

JPQL语句的大小写敏感性:

除了Java类和属性名称外,查询都是大小写不敏感的。

所以,SeLeCT和sELEct以及SELECT相同的,但是com.foshanshop.ejb3.bean.Person和com.foshanshop.ejb3.bean.PERSon是不同的,person.name和person.NAME也是不同的。

命名查询

可以在实体bean上通过@NamedQueryor@NamedQueries预先定义一个或多个查询语句,减少每次因书写错误而引起的BUG。

通常把经常使用的查询语句定义成命名查询。

定义单个命名查询:

@NamedQuery(name="

getPerson"

query="

FROMPersonWHEREpersonid=?

@Entity

publicclassPersonimplementsSerializable{

如果要定义多个命名查询,应在@javax.persistence.NamedQueries里定义@NamedQuery:

@NamedQueries({

),

getPersonList"

FROMPersonWHEREage>

?

})

当命名查询定义好了之后,我们就可以通过名称执行其查询。

代码如下:

Queryquery=em.createNamedQuery("

query.setParameter(1,1);

排序(orderby)

"

ASC"

和"

DESC"

分别为升序和降序,JPQL中默认为asc升序

//先按年龄降序排序,然后按出生日期升序排序

selectpfromPersonporderbyp.agedesc,p.birthdayasc"

查询部分属性

通常来说,都是针对Entity类的查询,返回的也是被查询的Entity类的实体。

JPQL也允许我们直接查询返回我们需要的属性,而不是返回整个Entity。

在一些Entity中属性特别多的情况,这样的查询可以提高性能

//只查询我们感兴趣的属性(列)

Queryquery=em.createQuery("

selectp.personid,p.namefromPersonporderbyp.personiddesc"

//集合中的元素不再是Person,而是一个Object[]对象数组

Listresult=query.getResultList();

if(result!

=null){

Iteratoriterator=result.iterator();

while(iterator.hasNext()){

Object[]row=(Object[])iterator.next();

intpersonid=Integer.parseInt(row[0].toString());

StringPersonName=row[1].toString();

查询中使用构造器(Constructor)

JPQL支持将查询的属性结果直接作为一个javaclass的构造器参数,并产生实体作为结果返回。

例如上面的例子只获取personentitybean的nameandpersonid属性,我们不希望返回的集合的元素是object[],而希望用一个类来包装它。

就要用到使用构造器。

publicclassSimplePerson{

privateIntegerpersonid;

privateStringname;

publicSimplePerson(){

publicSimplePerson(Integerpersonid,Stringname){

this.name=name;

this.personid=personid;

查询代码为:

//我们把需要的两个属性作为SimplePerson的构造器参数,并使用new函数。

selectnewcom.foshanshop.ejb3.bean.SimplePerson(p.personid,p.name)fromPersonporderbyp.personiddesc"

//集合中的元素是SimplePerson对象

SimplePersonsimpleperson=(SimplePerson)iterator.next();

聚合查询(Aggregation)

JPQL支持的聚合函数包括:

1.AVG()

2.SUM()

3.COUNT(),返回类型为Long,注意count(*)语法在hibernate中可用,但在toplink其它产品中并不可用

4.MAX()

5.MIN()

//获取最大年龄

selectmax(p.age)fromPersonp"

Objectresult=query.getSingleResult();

StringmaxAge=result.toString();

//获取平均年龄

query=em.createQuery("

selectavg(p.age)fromPersonp"

//获取最小年龄

selectmin(p.age)fromPersonp"

//获取总人数

selectcount(p)fromPersonp"

//获取年龄总和

selectsum(p.age)fromPersonp"

如果聚合函数不是select...from的唯一一个返回列,需要使用"

GROUPBY"

语句。

应该包含select语句中除了聚合函数外的所有属性。

//返回男女生各自的总人数

selectp.sex,count(p)fromPersonpgroupbyp.sex"

如果还需要加上查询条件,需要使用"

HAVING"

条件语句而不是"

WHERE"

语句

//返回人数超过1人的性别

selectp.sex,count(p)fromPersonpgroupbyp.sexhavingcount(*)>

//设置查询中的参数

query.setParameter(1,newLong

(1));

关联(join)

JPQL仍然支持和SQL中类似的关联语法:

leftoutjoin/leftjoin

innerjoin

leftjoinfetch/innerjoinfetch

leftoutjoin/leftjoin等,都是允许符合条件的右边表达式中的Entiies为空(需要显式使用leftjoin/leftouterjoin的情况会比较少。

//获取26岁人的订单,不管Order中是否有OrderItem

selectofromOrderoleftjoino.orderItemswhereo.ower.age=26orderbyo.orderid

innerjoin要求右边的表达式必须返回Entities。

//获取26岁人的订单,Order中必须要有OrderItem

selectofromOrderoinnerjoino.orderItemswhereo.ower.age=26orderbyo.orderid

重要知识点:

在默认的查询中,Entity中的集合属性默认不会被关联,集合属性默认是延迟加载(lazy-load)。

那么,leftfetch/leftoutfetch/innerjoinfetch提供了一种灵活的查询加载方式来提高查询的性能。

privateStringQueryInnerJoinLazyLoad(){

//默认不关联集合属性变量(orderItems)对应的表

selectofromOrderoinnerjoino.orderItemswhereo.ower.age=26orderbyo.orderid"

=null&

&

result.size()>

0){

//这时获得Order实体中orderItems(集合属性变量)为空

Orderorder=(Order)result.get(0);

//当需要时,EJB3Runtime才会执行一条SQL语句来加载属于当前Order的

//OrderItems

Set<

OrderItem>

list=order.getOrderItems();

Iterator<

iterator=list.iterator();

if(iterator.hasNext()){

OrderItemorderItem=iterator.next();

System.out.println("

订购产品名:

+orderItem.getProductname());

上面代码在执行"

时编译成的SQL如下(他不包含集合属性变量(orderItems)对应表的字段):

selectorder0_.orderidasorderid6_,order0_.amountasamount6_,order0_.person_idas

person4_6_,order0_.createdateascreatedate6_fromOrdersorder0_innerjoinOrderItems

orderitems1_onorder0_.orderid=orderitems1_.order_id,Personperson2_where

order0_.person_id=person2_.personidandperson2_.age=26orderbyorder0_.orderid

上面代码当执行到Set<

时才会执行一条SQL语句来加载属于当前Order的OrderItems,编译成的SQL如下:

selectorderitems0_.order_idasorder4_1_,orderitems0_.idasid1_,orderitems0_.idasid7_0_,

orderitems0_.order_idasorder4_7_0_,orderitems0_.productnameasproductn2_7_0_,

orderitems0_.priceasprice7_0_fromOrderItemsorderitems0_whereorderitems0_.order_id=?

orderbyorderitems0_.idASC

这样的查询性能上有不足的地方。

为了查询N个Order,我们需要一条SQL语句获得所有的Order的原始对象属性,但需要另外N条语句获得每个Order的orderItems集合属性。

为了避免N+1的性能问题,我们可以利用joinfetch一次过用一条SQL语句把Order的所有信息查询出来

例子

selectofromOrderoinnerjoinfetcho.orderItemswhere

o.ower.age=26orderbyo.orderid"

上面这句HPQL编译成以下的SQL:

selectorder0_.orderidasorderid18_0_,orderitems1_.idasid19_1_,order0_.amountas

amount18_0_,order0_.person_idasperson4_18_0_,order0_.createdateascreatedate18_0_,

orderitems1_.order_idasorder4_19_1_,orderitems1_.productnameasproductn2_19_1_,

orderitems1_.priceasprice19_1_,orderitems1_.order_idasorder4_0__,orderitems1_.idasid0__

fromOrdersorder0_innerjoinOrderItemsorderitems1_on

order0_.orderid=orderitems1_.order_id,Personperson2_where

order0_.person_id=person2_.personidandperson2_.age=26orderbyorder0_.orderid,

orderitems1_.idASC

上面由于使用了fetch,这个查询只会产生一条SQL语句,比原来需要N+1条SQL语句在性能上有了极大的提升

排除相同的记录DISTINCT

使用关联查询,我们很经常得到重复的对象,如下面语句:

selectofromOrderoinnerjoinfetcho.orderItemsorderbyo.orderid"

当有N个orderItem时就会产生N个Order,而有些Order对象往往是相同的,这时我们需要使用DISTINCT关键字来排除掉相同的对象。

selectDISTINCTofromOrderoinnerjoinfetcho.orderItemsorderbyo.orderid

比较Entity

在查询中使用参数查询时,参数类型除了String,原始数据类型(int,double等)和它们的对象类型(Integer,Double等),也可以是Entity的实例。

//查询某人的所有订单

selectofromOrderowhereo.ower=?

1orderbyo.orderid"

Personperson=newPerson();

person.setPersonid(newInteger

(1));

query.setParameter(1,person);

批量更新(BatchUpdate)

HPQL支持批量更新

//把所有订单的金额加10

updateOrderasoseto.amount=o.amount+10"

//update的记录数

intresult=query.executeUpdate();

批量删除(BatchRemove)

//把金额小于100的订单删除,先删除订单子项,再删除订单

deletefromOrderItemitemwhereitem.orderin(fromOrderasowhereo.amount<

100)"

query.executeUpdate();

deletefromOrderasowhereo.amount<

100"

//delete的记录数

使用操作符NOT

//查询除了指定人之外的所有订单

selectofromOrderowherenot(o.ower=?

1)orderbyo.orderid"

person.setPersonid(newInteger

(2));

使用操作符BETWEEN

selectofromOrderasowhereo.amountbetween300and1000

使用操作符IN

//查找年龄为26,21的Person

selectpfromPersonaspwherep.agein(26,21)

使用操作符LIKE

//查找以字符串"

li"

开头的Person

selectpfromPersonaspwherep.namelike'

li%'

使用操作符ISNULL

//查询含有购买者的所有Order

selectofromOrderasowhereo.oweris[not]null

使用操作符ISEMPTY

ISEMPTY是针对集合属性(Collection)的操作符。

可以和NOT一起使用。

注:

低版权的Mysql不支持ISEMPTY

//查询含有订单项的所有Order

selectofromOrderasowhereo.orderItemsis[not]empty

使用操作符EXISTS

[NOT]EXISTS需要和子查询配合使用。

低版权的Mysql不支持EXISTS

//如果存在订单号为1的订单,就获取所有OrderItem

selectoifromOrderItemasoiwhereexists(selectofromOr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2