JPQL

Java Persistence API 定义了一种查询语言,具有与SQL 相类似的特征,JPQL 是完全面向对象的,具备继承、多态和关联等特性 (可参考持久化产品使用手册,如Hibernate,Kodo,Toplink)
查询都是大小写不敏感的
1.查询
   select count(p) from Person p

2.命名查询
@NamedQueries(
    {
        @NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1"),
        @NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1")
    }
)
...
Query query=em.createNamedQuery("getPerson");

3.排序
   排序和SQL的语法类似
   select p from Person p order by p.age desc, p.birthday asc

4.查询Entity Bean 的部分属性
   Query query = em.createQuery("select p.personid, p.name from Person p order by p.personid desc ");
   //集合中的元素不再是Person,而是一个Object[]对象数组
   List result = query.getResultList();
   Iterator iterator = result.iterator();
   while( iterator.hasNext() ){
   //取每一行
   Object[] row = ( Object[]) iterator.next();
   //数组元素的顺序和查询时的参数顺序一样
    int personid = Integer.parseInt(row[0].toString());
    String PersonName = row[1].toString();
    }

5.查询中使用构造器
   EJB3 QL 支持将查询的属性结果直接作为一个java class 的构造器参数,并产生实体作为结果返回
   例
   //我们把需要的两个属性作为SimplePerson 的构造器参数,并使用new 函数。
   Query query = em.createQuery("select new xxx.xxx.SimplePerson(p.name,p.sex) from Person p order by p.personid desc");
   //集合中的元素是SimplePerson 对象
   List result = query.getResultList();

6.聚合查询
   和SQL 一样,如果聚合函数不是select...from 的唯一一个返回列,需要使用"GROUP BY"语句。"GROUP BY"应该包含select 语句中除了聚合函数外的所有属性,如果还需要加上查询条件,需要使用"HAVING"条件语句而不是"WHERE"语句
   
EJB3 QL 支持的聚合函数:
   1. AVG() : select avg(p.age) from Person p
   2. SUM() : select sum(p.age) from Person p
   3. COUNT() : select count(p) from Person p
       返回类型为Long,注意count(*)语法在hibernate 中可用,但在toplink 其它产品中并不可用
   4. MAX() : select max(p.age) from Person p
   5. MIN() : select min(p.age) from Person p
GROUP BY的例子:
//返回男女生各自的总人数
Query query = em.createQuery("select p.sex, count(p) from Person p group by p.sex");
//集合中的元素不再是Person,而是一个Object[]对象数组
List result = query.getResultList();
Iterator iterator = result.iterator();
while( iterator.hasNext() ){
          //取每一行
          Object[] row = (Object[]) iterator.next();
          //数组中的第一个值是sex
          boolean sex = Boolean.parseBoolean(row[0].toString());
          //数组中的第二个值是聚合函数COUNT 返回值
          String sextotal = row[1].toString();
}

HAVING例子
Query query = em.createQupery("select p.sex, count(p) from Person p group by p.sex having count(*)>?1");

7:关联
   在EJB3 QL 中,仍然支持和SQL 中类似的关联语法:
   left out join/left join
         都是允许符合条件的右边表达式中的Entiies为空
         //获取26 岁人的订单,不管Order 中是否有OrderItem
         Query query = em.createQuery("select o from Order o  left join  o.orderItems where o.ower.age=26
order by o.orderid");
          不加上left join也可以,需要显式使用left join/left outer join 的情况会比较少
   inner join
          右边的表达式必须返回Entities
          //获取26 岁人的订单,Order 中必须要有OrderItem
        Query query = em.createQuery("select o from Order o inner join o.orderItems where o.ower.age=26
order by o.orderid");
   left join/inner join fetch
   left/left out/inner join fetch 提供了一种灵活的查询加载方式来提高查询的性能。在默认的查询中,Entity 中的集合属性默认不会被关联,集合属性默认是缓加载( lazy-load ),这样的查询性能上有不足的地方。为了查询N 个Order,我们需要一条SQL 语句获得所有的Order 的原始对象属性, 但需要另外N 条语句获得每个Order 的orderItems 集合属性。为了避免N+1 的性能问题,我们可以利用join fetch 一次过用一条SQL 语句把Order 的所有信息查询出来.
//获取26 岁人的订单,Order 中必须要有OrderItem
   Query query = em.createQuery("select o from Order o inner join fetch o.orderItems where
o.ower.age=26 order by o.orderid");
使用fetch,这个查询只会产生一条SQL 语句,比原来需要N+1 条SQL 语句在性能上有了极大的提升

8.排除相同的记录DISTINCT
    使用关联查询,我们很经常得到重复的对象,如下面语句:
    "select o from Order o inner join fetch o.orderItems order by o.orderid "
    当有N 个orderItem 时就会产生N 个Order,而有些Order 对象往往是相同的
    使用DISTINCT 关键字来排除掉相同的对象 :
    Query query = em.createQuery("select DISTINCT o from Order o inner join fetch o.orderItems
order by o.orderid");
    不同的Order对象只有一个

9.比较Entity
   在查询中使用参数查询时,参数类型除了String, 原始数据类型( int, double 等)和它们的对象类型( Integer, Double等),也可以是Entity 的实例.
   //查询某人的所有订单
<!-- Order的ower属性是一个Person对象 -->
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();
...

10.批量更新(Batch Update)
     EJB3 QL 支持批量更新.
     //把所有订单的金额加10
     Query query = em.createQuery("update Order as o set o.amount=o.amount+10");
     //update 的记录数
     int result = query.executeUpdate();

11.批量删除(Batch Remove)
     EJB3 QL 支持批量删除
     //把金额小于100的订单删除,先删除订单子项,再删除订单
     Query query = em.createQuery("delete from OrderItem item where item.order in(from Order as
o where o.amount<100)");
     query.executeUpdate();
     query = em.createQuery("delete from Order as o where o.amount<100");
     int result = query.executeUpdate();//delete的记录数
...

12.使用操作符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);
     List result = query.getResultList();
...

13.使用操作符BETWEEN
     //查询金额在300 到1000 之间的订单
     Query query = em.createQuery("select o from Order as o where o.amount between 300 and 1000");
     List result = query.getResultList();
...

14.使用操作符IN
     //查找年龄为26,21 的Person
     Query query = em.createQuery("select p from Person as p where p.age in(26,21)");
     List result = query.getResultList();
...
15.使用操作符LIKE
     //查找以字符串"li"开头的Person
     Query query = em.createQuery("select p from Person as p where p.name like 'li%'");
     List result = query.getResultList();.
...

16.使用操作符IS NULL
     //查询含有购买者的所有Order
     Query query = em.createQuery("select o from Order as o where o.ower is not null order by
o.orderid");
     List result = query.getResultList();
...

17.使用操作符IS EMPTY
     IS EMPTY 是针对集合属性(Collection)的操作符.可以和NOT 一起使用
     //查询含有订单项的所有Order
     Query query = em.createQuery("select o from Order as o where o.orderItems is not empty order by
o.orderid");
     List result = query.getResultList();
...

18.使用操作符EXISTS
     [NOT]EXISTS 需要和子查询配合使用
     //如果存在订单号为1 的订单,就获取所有OrderItem
     Query query = em.createQuery("select oi from OrderItem as oi where exists (select o from Order o
where o.orderid=1)");
     List result = query.getResultList();
...

19.字符串函数
     EJB3 QL 定义了内置函数方便使用.这些函数的使用方法和SQL 中相应的函数方法类似.EJB3 QL 中定义的字符串函数包括:
     1. CONCAT 字符串拼接
         //查询所有人员,并在姓名后面加上字符串"_some"
         Query query = em.createQuery("select p.personid, concat(p.name, '_some') from Person as p");
         ...
     2. SUBSTRING 字符串截取
         //查询所有人员,只取姓名的前三个字符
        Query query = em.createQuery("select p.personid, substring(p.name,1,3) from Person as p");
        ...
     3. TRIM 去掉空格
          
     4. LOWER 转换成小写
     5. UPPER 装换成大写
     6. LENGTH 字符串长度
     7. LOCATE 字符串定位

20.计算函数
     EJB3 QL 中定义的计算函数包括:
     ABS 绝对值
             
     SQRT 平方根
     MOD 取余数
              //查询所有Order 的订单号及其总金额/10 的余数
              Query query = em.createQuery("select o.orderid, mod(o.amount, 10) from Order as o");
              ...
     SIZE 取集合的数量
              //查询所有Order 的订单号及其订单项的数量
             Query query = em.createQuery("select o.orderid, size(o.orderItems) from Order as o group by
o.orderid");

21.子查询
     
子查询可以用于WHERE 和HAVING 条件语句中
      //查询年龄为26 岁的购买者的所有Order
      Query query = em.createQuery("select o from Order as o where o.ower in(select p from Person as p
where p.age =26) order by o.orderid");
...

22.结果集分页
     
有些时候当执行一个查询会返回成千上万条记录,事实上我们只需要显示一部分数据。这时我们需要对结果集进行分页,QueryAPI 有两个接口方法可以解决这个问题:setMaxResults( ) 和setFirstResult( )
setMaxResults 方法设置获取多少条记录setFirstResult 方法设置从结果集中的那个索引开始获取(假如返回的记录有3 条,容器会自动为记录编上索引,索引从0 开始,依次为0,1,2)
例子:
     Query query = em.createQuery("from Person p order by personid asc");
     List list =  query.setMaxResults(max).setFirstResult(index).getResultList();
     em.clear();//分离内存中受EntityManager管理的实体bean,让VM进行垃圾回收
     ...
如果我们需要显示大量的实体Bean,假如记录成千上万,通过简单的循环处理,我们将很快消耗完内存,为此我们需要在显示了一部分实体bean 之后调用EntityManager.clear()及时把这些实体bean 从EntityManager 分离出来,让Java VM 对他们进行垃圾回收
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值