现在的位置: 首页 > 综合 > 正文

EJB3.0笔记-实体查询与EJB QL

2018年01月25日 ⁄ 综合 ⁄ 共 3873字 ⁄ 字号 评论关闭
在java persistence中,可以同时使用EJB QL查询语言和原生的SQL来完成查询操作。由于EJB QL是一种描述Java对象的查询语言,而entity manager会为你处理由EJB QL向原生SQL转换的工作,因此它具有跨数据库厂商实现的移植能力。EJB QL比SQL更加紧凑和更容易阅读,但是EJB QL不可能都支持数据库所有私有特性,所以功能上没有厂商原生SQL那么功能全面。

Query API
通过javax.persistence.Query接口来实现查询功能,而Query接口可以通过javax.persistence. EntityManager得到。

参数
EJB QL支持具名参数(named parameters)和指示参数(positional parameters),如:
Query query=entityManager.createQuery(“from Customer c where c.firstName=:first and
c.lastName=:last”);
query.setParameter(“first”,first);
query.setParameter(“last”,last);
return query.getResultList();
或者
Query query=entityManager.createQuery(“from Customer c where c.firstName=?1 and
c.lastName=?2”);
query.setParameter(1,first);
query.setParameter(2,last);
return query.getResultList();

日期型参数
如果要将java.util.Date或java.util.Calendar参数传入查询中,就得使用特殊的setParameter方法,
如下:
setParameter(String name,java.util.Date value,TemporalType temporalType);
setParameter(String name,Calendar value,TemporalType temporalType);
其中temporalType表示将Date或Calendar参数转换成原生SQL类型时,使用的是何种数据库类型

对结果分页
Query query=entityManager.createQuery(“from Customer c”);
return query.setMaxResults(max).setFirstResult(index).getResultList();

Hints
有些java.persistence厂商会为你提供一些能在执行查询时使用的附加功能,比如Jboss的EJB3.0允许 为查询定义超时。
Query query=entityManager.createQuery(“from Customer c”);
query.setHint(“org.hibernate.timeout”,1000);

FlushMode
默认的flush模式,会在em查询之前,执行flush动作(把更新同步到数据库)。如果希望在查询前不执行 flush,可以通过
Query query=entityManager.createQuery(“from Customer c”);
query.setFlushMode(FlushModeType.COMMIT);

EJB QL
EJB QL是按照实体的抽象持久结构来表达的,包括:抽象结构名称、基本成员属性和关系型成员属性。抽象结构名,默认是非限定类名,如果使用了
@Entity(name=”Cust”)
public class Customer{….}
那么查询Customer 的EJB QL为 select c from Cust AS c;

简单查询
select object(c) from Customer as c 等价于select c from Customer as c

选择实体和关系型成员属性
对于
@Entity
public class Customer{
private int id;
private String first;
private Address address;
@Id
public int getId(){…..}
public getFirstName(){return first;}
…………
}
选择成员属性可以使用:
select c.firstName from Customer as c;或者
select c.first from Customer as c;
选择关联的实体可以使用:
select c.address from Customer as c;
选择关联实体的属性可以使用:
select c.address.city from Customer as c;
但是如果Address不是持久型成员,只是普通的class,上面的语句是非法的。可以使用
@Embedded private Address address;让语句变回合法。

构造函数表达式
可以在select子句是指定一个构造函数,用于创建普通的JAVA对象(而非实体),如:
select new com.tian.domain.Name(c.firstName,c.lastName) from Customer c;

IN操作符和INNER JOIN
返回所有乘客的所有预订信息
select r from Customer as c ,in(c.reservations) r;
等效于
select r from Customer as c inner join c.reservations r;//inner可以省略

LEFT JOIN
查询所有顾客及他们的电话号码,如果顾客没有电话号码以null代替
select c.firstName ,p.number from Customer c left join c.phoneNumbers p;
//left join可以写成left outer join

Fetch Joins
如果关系型成员属性FetchType在定义XML时(或注解)设为LAZY,那么在程序访问到这些成员时才从数据库加载数据,有时会增加数据库访问量,可以通过JOIN FETCH强制加载这些关系成员,如:
select c from customer c left join fetch c.phones;这时会提前加载Phone关联

使用DISTINCT
关键字distinct确保查询不会返回重复项。如查询所有预订舱位的顾客,由于顾客可以预订多次,所有distinct可以派上用场。
select distinct cust from Reservation as res, in (res.customers) cust;

where 子句与字面常量
where 子句用于缩小选择范围。如果使用到字符串常量,可以使用单引号括起来,如果字符串中又有一个单引号,请用两个单引号表示;如果是数值型的常量,就直接书写;如果是布尔型,常量取值用true和false。如
where name=’capital one’; where name=’wendy’’s’;where hasGoodCredit=true;
如果不想涉及这些细节,可以直接使用查询参数,让查询API处理这些问题

where 子句与运算符的优先级
点号(.)à数学运算符(+-*/)à比较运算符(=,>,like,between,in,is null,is empty,member of)à逻辑运算符(not,and or)

where子句与数学运算符
允许查询操作在做比较时执行算术运算。运算过程中,数值也许被放宽或提升,如int 与double相乘,先把int 变成double,结果也是double的

where子句和逻辑运算符

and 和or运算符的行为与java语言中的&&和||有所不同。&&只有左操作数为true时才会对右操作数求值,and要由转换出的原生语言决定

where 子句和in

IN用来检验是否与一组字面常量中的元素相匹配,如:
where c.address.state IN(‘FL’,’TX’,’WI’);
也可以使用参数
where c.address.state IN(?1,?2,?3,5.7);
where 子句与is null
比较运算符is null允许检验路径表达式是否为null。它也可以用来检验输入参数,如
select c from Customer as c
where :city is not null and :state is not null
and c.address.state=:state

where 子句与is empty

is empty检验集合类型的关系是否为空(没有元素),集体类型的关系是从不会为null的。对from子句已经被赋予标识符的集合型关系使用is empty是非法的,如:
select r from Reservation as r inner join r.customers as c //已经赋予标识符c,表明c一定不为空
where r.customers is not empty;

where 子句与member of

member of用于判断某个实体是否是集合型关系的一个成员,如
where cust not member of res.customers

where子句与like

可以使用两个特殊的字符“%”(表示任意字符序列)和“_”(表示单个字符),如果字符串本来就有%或_,可以使用“\”字符来避免冲突

函数表达式
字符串处理函数
LOWER(String):转换成小写
UPPER(String):转换成大家

抱歉!评论已关闭.