EJB>JPQL 语言 小强斋

Java Persistence API 定义了一种查询语言,具有与SQL 相类似的特征,JPQL 是完全面向对象的,具备继承、多态和关联等特性
 
1、命名查询
你可以在实体bean 上预先定义一个或多个查询语句,减少每次因书写错误而引起的BUG。通常把经常使用的查询语句定义成命名查询,代码如下:
@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1")
@Entity
@Table(name = "Person")
public class Person implements Serializable{

如果你需要定义多个命名查询,应在@javax.persistence.NamedQueries 注释里定义@NamedQuery,代码如下:

@NamedQueries({
@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1"),
@NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1")
})
@Entity@Table(name = "Person")public class Person implements Serializable{

 

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

Query query = em.createNamedQuery("getPerson");query.setParameter(1, 1);

2、如果不显式注明,EJB3 QL 中默认为asc 升序。
3、查询部分属性
Query query = em.createQuery("select p.personid, p.name from Person p order by p.personid desc ");
4、查询中使用构造器(Constructor)
private String QueryConstructor(){
//我们把需要的两个属性作为SimplePerson 的构造器参数,并使用new 函数。
Query query = em.createQuery("select new com.foshanshop.ejb3.bean.SimplePerson(p.name,p.sex)
from Person p order by p.personid desc");
//集合中的元素是SimplePerson 对象
List result = query.getResultList();
StringBuffer out = new StringBuffer("*************** QueryConstructor 结果打印
****************<BR>");
if (result!=null){

Iterator iterator = result.iterator();
while( iterator.hasNext() ){
SimplePerson simpleperson = (SimplePerson) iterator.next();
out.append("人员介绍:"+ simpleperson.getDescription()+ "<BR>");
}
}
return out.toString();
}



5、聚合函数
目前EJB3 QL 支持的聚合函数包括:
1. AVG()
2. SUM()
3. COUNT() ,返回类型为Long

4. MAX()
5. MIN()

和SQL 一样,如果聚合函数不是select...from 的唯一一个返回列,需要使用"GROUP BY"语句。"GROUP BY"应该包含select 语句中除了聚合函数外的所有属性
Query query = em.createQuery("select p.sex, count(p) from Person p group by p.sex");
如果还需要加上查询条件,需要使用"HAVING"条件语句而不是"WHERE"语句。
//返回人数超过1 人的性别
Query query = em.createQuery("select p.sex, count(p) from Person p group by p.sex having count(*)>?1");

query.setParameter(1, new Long(1));
6、关联(join)
left out join/left join 等都是允许符合条件的右边表达式中的Entiies 为空。
//获取26 岁人的订单,不管Order 中是否有OrderItem
Query query = em.createQuery("select o from Order o left join o.orderItemswhere o.ower.age=26
order by o.orderid");
inner join 要求右边的表达式必须返回Entities
Query query = em.createQuery("select o from Order oinner join o.orderItemswhere o.ower.age=26 order by o.orderid");
fetch 提供了一种灵活的查询加载方式来提高查询的性能。在默认的查询中,Entity 中的集合属性默认不会被关联,集合属性默认是缓加载( lazy-load )。
"select o from Order o inner joino.orderItems where o.ower.age=26 order by o.orderid"
为了查询N 个Order,我们需要一条SQL 语句获得所有的Order 的原始对象属性, 但需要另外N 条语句获得每Order 的orderItems 集合属性。为了避免N+1 的性能问题,我们可以利用joinfetch 一次过用一条SQL 语句把Order 的所有信息查询出来
//获取26 岁人的订单,Order 中必须要有OrderItem
Query query = em.createQuery("select o from Order o inner join fetcho.orderItems where o.ower.age=26 order by o.orderid");
7、排除相同的记录DISTINCT
Query query = em.createQuery("select DISTINCT o from Order o inner join fetch o.orderItems order by o.orderid");
8、在查询中使用参数查询时,参数类型可以是Entity 的实例
Query query = em.createQuery("select o from Order o where o.ower =?1 order by o.orderid");
Person person = new Person();
person.setPersonid(new Integer(1));
//设置查询中的参数
query.setParameter(1,person);
List result = query.getResultList();
9、使用操作符NOT
//查询除了指定人之外的所有订单
Query query = em.createQuery("select o from Order o where not(o.ower =?1) order by o.orderid");
Person person = new Person();
person.setPersonid(new Integer(2));
//设置查询中的参数
query.setParameter(1,person);
10、 使用操作符BETWEEN
Query query = em.createQuery("select o from Order as o where o.amount between 300 and 1000");
11、 使用操作符IN
Query query = em.createQuery("select p from Person as p where p.age in(26,21)");
12、 使用操作符LIKE
Query query = em.createQuery("select p from Person as p where p.name like 'li%'");
13、使用操作符IS NULL
Query query = em.createQuery("select o from Order as o where o.ower is not null order byo.orderid");
14、 使用操作符IS EMPTY
IS EMPTY 是针对集合属性(Collection)的操作符。可以和NOT 一起使用
Query query = em.createQuery("select o from Order as o where o.orderItems is not empty order byo.orderid");
15、 使用操作符EXISTS  [NOT]EXISTS 需要和子查询配合使用
//如果不存在订单号为10 的订单,就获取id 为1 的OrderItem
query = em.createQuery("select oi from OrderItem as oi where oi.id=1 and not exists (select o from
Order o where o.orderid=10)");
//如果存在订单号为1 的订单,就获取所有OrderItem
Query query = em.createQuery("select oi from OrderItem as oi where exists (select o from Order o
where o.orderid=1)");

16、字符串函数EJB3 QL 中定义的字符串函数包括:
1. CONCAT 字符串拼接
2. SUBSTRING 字符串截取
3. TRIM 去掉空格
4. LOWER 转换成小写
5. UPPER 装换成大写
6. LENGTH 字符串长度
7. LOCATE 字符串定位

Query query = em.createQuery("select p.personid, concat(p.name, '_foshan') from Person as p");

17、 计算函数
EJB3 QL 中定义的计算函数包括:
ABS 绝对值
SQRT 平方根
MOD 取余数
SIZE 取集合的数量
//查询所有Order 的订单号及其订单项的数量
Query query = em.createQuery("select o.orderid, size(o.orderItems) from Order as o group by
o.orderid");
20 子查询
子查询可以用于WHERE 和HAVING 条件语句中
21 结果集分页
有些时候当执行一个查询会返回成千上万条记录,事实上我们只需要显示一部分数据。这时我们需要对结果集进行分页,QueryAPI 有两个接口方法可以解决这个问题:setMaxResults( ) 和setFirstResult( )
setMaxResults 方法设置获取多少条记录,setFirstResult 方法设置从结果集中的那个索引开始获取(假如返回的记录有3 条,容器会自动为记录编上索引,索引从0 开始,依次为0,1,2)
public List getPersonList(int max,int whichpage) {
try {
int index = (whichpage-1) * max;
Query query = em.createQuery("from Person p order by personid asc");
List list = query.setMaxResults(max).
setFirstResult(index).
getResultList();
em.clear();//分离内存中受EntityManager管理的实体bean,让VM进行垃圾回收
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

 
 
原文地址:https://www.cnblogs.com/xiaoqiangzhaitai/p/5429563.html