在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):转换成大家
TRIM([[leading|trailing|both][trim_char]from)]String):去除指定字符trim_char,默认为空格
CONCAT(String1,String2):连接字符串
LENGTH(String):求字符串长度
LOCATE(String1,String2[,start]):String1在String2的什么位置
SUBSTRING(String1,sart,length):截取字符串
数字函数
ABS(number):绝对值
SORT(double):平方根
MOD(int,int):求余数
返回日期和时间的函数
CURRENT_DATE:返回当前日期
CURRENT_TIME:返回当前时间
CURRENT_TIMESTAMP:返回当前时间戳
聚合函数
COUNT():返回查询结果集中的条目数
MAX():找出最大值
MIN():找出最小值
AVG(numeric):平均值
SUM(numerc):求和
ORDER BY子句
对返回集合进行排序。在EJB QL中有一个使用限制:order by子句中出现的属性,必须出现在select子句中,或者是select子句选中实体的一个属性。如:
select c from Customers as c order by c.address desc;select addr.zip from Address as addr order by add.zip;
以下是非法的
select c from Customers as c order by c.address.city desc;// city不是c的直接属性
GROUP BY 与HAVING
group by 用于分组,having对分组进一步筛选。group by子句中指定的字段必须出现于查询的返回结果中,这和SQL的要求是一致的。
子查询
子查询是内嵌于主查询的另一个查询。EJB QL支持在where和having子句中使用子查询
查询费用超过$100,000的所有航程
from Cruise cr where 100000<(select sum(res.amountPaid) from cr.reservations res)
ALL,ANY,SOME
如果子查询返回多项结果,可以使用ALL、ANY和SOME对结果做进一步限定
如果子查询中的所有内容都与条件表达式相匹配,那么操作符ALL就返回true
查询所有预付了舱位预订定金的航程
from Cruise cr where 0< all(select res.amountPaid from cr.reservations res)
如果子查询中的有任意一项与条件表达式相匹配,那么操作符ALL或SOME就返回true
EXISTS
如果子查询包含一项或多项结果,那么操作符EXISTS返回true
批量的UPDATE与DELETE
给所有名叫Bill Burke的乘客增加$10
update Reservation res set res.amountPaid=(res.amountPaid+10)
where exists(
select c from res.customers c
where c.firstName=’Bill’ and c.lastName=’Burke’
);
是否可以写成?
update Reservation res set res.amountPaid=(res.amountPaid+10)
where res.customers.firstName=’Bill’ and res.customers.lastName=’Burke’
删除所有Bill Burke的舱位预订记录
delect from Reservation res
where exist(
select c from res.customers c
where c.firstName=’Bill’ and c.lastName=’Burke’
)
原生查询
EntityManager接口有三个创建原生查询的方法:一个返回标量值,一个返回实体类型,还有一个返回多个实体与标量值组合
标量原生查询
createNativeQuery(String sql);
简单实体的原生查询
createNativeQuery(String sql,Class entityClass);根据某个实体定义好的映射元数据,将返回值映射到该实体
复杂原生查询
createNativeQuery(String sql,String mappingName)
返回多个实体
@Entity
@SqlResultSetMapping(name=”customerAndCreditCardMapping”,//映射名
entities={@EntityResult(entityClass=Customer.class),//entities指定映射的实体
@EntityResult(entityClass=CreditCard.class,
fields={@FieldResult(name=”id”,column=”CC_ID”),//指定实体内成员与返回字段的映射
@FieldResult(name=”number”,column=”number”)})
})
public class Customer{………}
等价XML
<entity-mappings>
<sel-result-set-mapping name=” customerAndCreditCardMapping”>
<entity-result entity-class=”com.titan.domain.Customer”/>
<entity-result entity-class=”com.titan.domain.CreditCard”>
<field-result name=”id” column=”CC_ID”/>
<field-result name=”number” column=”number”/>
</entity-result>
</sel-result-set-mapping>
</entity-mappings>
使用方法
String sql=”select c.id,c.firstName,cc.id As CC_IC,cc.number from CUST_TABEL
c,CREDIT_CARD_TABLE cc….”
manager.createNativeQuery(sql,”customerAndCreditCardMapping”);
返回结果既有标量也有实体
@SqlResultSetMapping(name=”reservationCount”,//映射名
entities={@EntityResult(entityClass=Cruise.class,
fields={@FieldResult(name=”id”,column=”id”) })},
columns={@ColumnsResult(name=”resCount”)}//标量
)
@Entity
public class Cruise{……}
等价XML
<entity-mappings>
<sel-result-set-mapping name=” reservationCount”>
<entity-result entity-class=”com.titan.domain.Cruise”>
<field-result name=”id” column=”id”/>
</entity-result>
<column-result name=”resCount”>
</sel-result-set-mapping>
</entity-mappings>
使用方法
String sql=”select c.id,count(Resrvation.id) as resCount from Cruise c left join
Reservation on c.id=………..”;
manager.createNativeQuery(sql,” reservationCount”);
具名EJB QL查询
预先定义好EJB QL或原生的SQL查询
使用@javax.persistence.NamedQuery用来预定EJB QL的,NamedQuerys用于定义多条查询
@NamedQuerys({
NamedQuery(name=”getAverageReservateion”,//名字
query=”select AVG(r.amountPaid) from Cruise As c Join c.reservatons r where
c=:cruise”),//EJB QL
NamedQuery(……)
})
@Entity
public class Cruise{…….}
等价XML
<entity-mapping>
<named-query name=” getAverageReservateion”>
<query>
EJB QL
</query>
</ named-query >
</entity-mapping >
使用方式
Query query=em.createNamedQuery(“getAverageReservateion”);
query.setParameter(“cruise”.cruise);
具名原生查询
使用@javax.persistence.NamedNativeQuery注解来预定义具名原生SQL查询
@NamedNativeQuery(
name=”findCustAndCCNum”,
query=”select ……..”,//原生SQL
resultClass=”…”,//只返回一个实体时用
resultSetMapping=”….”
//一个声明的@SqlResultSetMapping,用于返回多个实体和或实体与标量混合的查询
)
等价XML
<entity-mappings>
<named-native-query name=” getAverageReservateion” result-set-mapping=”….”>
<query>
原生SQL
</query>
</ named-native-query >
</entity-mappings >
使用方式
Query query=em.createNamedQuery(“getAverageReservateion”);
query.setParameter(“cruise”.cruise);
分享到:
相关推荐
- `ejb-3_0-fr-spec-ejbcore.pdf`:这部分详细阐述了EJB3.0的核心概念和实现,包括会话Bean、实体Bean以及容器服务。 - `ejb-3_0-fr-spec-persistence.pdf`:该文档专注于EJB3.0中的持久化机制,即JPA,解释了如何...
NULL 博文链接:https://xiaocong1001.iteye.com/blog/258852
- **PersistenceContext**: 提供与实体管理器交互的上下文。 - **PersistenceUnit**: 定义持久化单元,包含相关的实体类和配置信息。 **应用场景** EJB 3.0广泛应用于大型企业级应用,如电子商务、金融服务、库存...
《EJB3.0入门经典》是关于EJB 3.0的专业技术教程,从实用的角度出发,理论联系实际,用9章的篇幅详细讲解了EJB 3.0开发的方法和技巧。《EJB3.0入门经典》内容丰富,讲解由浅入深,全面系统,在讲解EJB 3.0最新开发...
NULL 博文链接:https://xiaocong1001.iteye.com/blog/252686
很不错的EJB教程,请大家好好珍惜 好好看
ejb-api-3.0-sources ejb3.0资源文件,源代码文件
### EJB2.0与EJB3.0的主要区别 #### 一、简介 企业Java Beans(EJB)是Java平台为企业级应用提供的一种组件模型。随着技术的发展,EJB经历了多个版本的迭代,其中EJB 2.0和EJB 3.0是两个重要的里程碑版本。本文将...
EJB 3.0移除了传统的部署描述符(ejb-jar.xml),许多元数据可以直接在Bean类上通过注解来定义,使得部署过程更加简单。 10. **测试支持(Testing Support)**: EJB 3.0引入了单元测试和集成测试的支持,使得...
### EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展 #### 一、概述 EJB3.0引入了一种新的编程模型,它基于Java Persistence API (JPA),使得开发人员能够更加轻松地创建企业级应用。JPA允许使用POJO(Plain Old...
EJB(Enterprise JavaBeans)...ejb-3_0-fr-spec-ejbcore.pdf、ejb-3_0-fr-spec-persistence.pdf和ejb-3_0-fr-spec-simplified.pdf这三份文档共同构成了EJB 3.0的完整知识体系,是深入理解EJB 3.0规范的重要参考资料。
标签:agent-ejb-3.0-beta-1-javadoc.jar,agent,ejb,3.0,beta,1,javadoc,jar包下载,依赖包
标签:agent-ejb-3.0-beta-1-sources.jar,agent,ejb,3.0,beta,1,sources,jar包下载,依赖包
9. **测试**:EJB 3.0引入了集成测试框架,如Arquillian,使得对EJB的单元测试和集成测试变得更加容易。 这个ejb3.0开发实例提供了完整的代码,对于初学者来说,是学习和理解EJB 3.0概念和实践操作的宝贵资源。你...
10. **部署描述符**:EJB 3.0的部署描述符(ejb-jar.xml)大大简化,许多配置信息可以通过注解直接在源代码中指定,降低了部署的复杂性。 以上是EJB 3.0的核心概念和特性,通过这些知识点的学习,开发者可以更好地...
#### 四、EJB 3.0与Spring框架的对比 - **竞争与互补**:尽管Spring框架和Hibernate提供了类似的事务管理和持久化服务,但EJB 3.0更适合于需要分布式能力的应用场景。Spring框架侧重于提供轻量级的解决方案,而EJB ...
标签:agent-car-ejb-3.0-beta-1-sources.jar,agent,car,ejb,3.0,beta,1,sources,jar包下载,依赖包
标签:agent-ejb-3.0-beta-1.jar,agent,ejb,3.0,beta,1,jar包下载,依赖包