EJB---->JPQL 语言

来源:互联网 发布:淘宝宝贝描述在哪里 编辑:程序博客网 时间:2024/06/06 19:34
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 中是否有OrderItemQuery query = em.createQuery("select o from Order o left join o.orderItemswhere o.ower.age=26order 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 中必须要有OrderItemQuery 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 的OrderItemquery = em.createQuery("select oi from OrderItem as oi where oi.id=1 and not exists (select o fromOrder o where o.orderid=10)");//如果存在订单号为1 的订单,就获取所有OrderItemQuery query = em.createQuery("select oi from OrderItem as oi where exists (select o from Order owhere 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 byo.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;}}

 
原创粉丝点击