使用二级缓存:
<shared-cache-mode> 节点:若 JPA 实现支持二级缓存,该节点可以配置在当前的持久化单元中是否启用二级缓存,可配置如下值:
ALL:所有的实体类都被缓存;
NONE:所有的实体类都不被缓存.;
ENABLE_SELECTIVE:标识 @Cacheable(true) 注解的实体类将被缓存;
DISABLE_SELECTIVE:缓存除标识 @Cacheable(false) 以外的所有实体类;
UNSPECIFIED:默认值,JPA 产品默认值将被使用.
JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。
JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query 接口封装执行;
Query接口封装了执行数据库查询的相关方法。调用 EntityManager 的 createQuery、create NamedQuery 及 createNativeQuery 方法可以获得查询对象,进而可调用 Query 接口的相关方法来执行查询操作。
Query接口的主要方法:
- int executeUpdate();用于执行update或delete语句。
- List getResultList() 用于执行select语句并返回结果集实体列表.
- Object getSingleResult() 用于执行只返回单个结果实体的select语句。
- Query setFirstResult(int startPosition) 用于设置从哪个实体记录开始返回查询结果。
- Query setMaxResults(int maxResult) 用于设置返回结果实体的最大数。与setFirstResult结合使用可实现分页查询。
- Query setFlushMode(FlushModeType flushMode) 设置查询对象的Flush模式。参数可以取2个枚举值:FlushModeType.AUTO 为自动更新数据库记录,FlushMode Type.COMMIT 为直到提交事务时才更新数据库记录。
- setHint(String hintName, Object value) 设置与查询对象相关的特定供应商参数或提示信息。参数名及其取值需要参考特定 JPA 实现库提供商的文档。如果第二个参数无效将抛出IllegalArgumentException异常。
- setParameter(int position, Object value) 为查询语句的指定位置参数赋值。Position 指定参数序号,value 为赋给参数的值。
- setParameter(int position, Date d, TemporalType type) 为查询语句的指定位置参数赋 Date 值。Position 指定参数序号,value 为赋给参数的值,temporalType 取 TemporalType 的枚举常量,包括 DATE、TIME 及 TIMESTAMP 三个,,用于将 Java 的 Date 型值临时转换为数据库支持的日期时间类型(java.sql.Date、java.sql.Time及java.sql.Timestamp);
- setParameter(int position, Calendar c, TemporalType type) 为查询语句的指定位置参数赋 Calenda r值。position 指定参数序号,value 为赋给参数的值,temporalType 的含义及取舍同前。
- setParameter(String name, Object value) 为查询语句的指定名称参数赋值。
- setParameter(String name, Date d, TemporalType type) 为查询语句的指定名称参数赋 Date 值。用法同前。
- setParameter(String name, Calendar c, TemporalType type) 为查询语句的指定名称参数设置Calendar值。name为参数名,其它同前。该方法调用时如果参数位置或参数名不正确,或者所赋的参数值类型不匹配,将抛出 IllegalArgumentException 异常。
select语句:from 子句是查询语句的必选子句。 Select 用来指定查询返回的结果实体或实体的某些属性 From 子句声明查询源实体类,并指定标识符变量(相当于SQL表的别名)。 如果不希望返回重复实体,可使用关键字 distinct 修饰。select、from 都是 JPQL 的关键字,通常全大写或全小写,建议不要大小写混用。
查询所有实体的 JPQL 查询字串很简单,例如: select o from Order o 或 select o from Order as o 关键字 as 可以省去。 标识符变量的命名规范与 Java 标识符相同,且区分大小写。
调用 EntityManager 的 createQuery() 方法可创建查询对象,接着调用 Query 接口的 getResultList() 方法就可获得查询结果集。例如:
Query query = entityManager.createQuery( "select o from Order o");
List orders = query.getResultList();
Iterator iterator = orders.iterator();
while( iterator.hasNext() ) { // 处理Order }
where子句:
where子句用于指定查询条件,where跟条件表达式。例: select o from Orders o where o.id = 1 select o from Orders o where o.id > 3 and o.confirm = 'true' select o from Orders o where o.address.streetNumber >= 123
JPQL也支持包含参数的查询,例如: select o from Orders o where o.id = :myId select o from Orders o where o.id = :myId and o.customer = :customerName
注意:参数名前必须冠以冒号(:),执行查询前须使用Query.setParameter(name, value)方法给参数赋值。
也可以不使用参数名而使用参数的序号,例如: select o from Order o where o.id = ?1 and o.customer = ?2
其中 ?1 代表第一个参数,?2 代表第一个参数。在执行查询之前需要使用重载方法Query.setParameter(pos, value) 提供参数值。
Query query = entityManager.createQuery( "select o from Orders o where o.id = ?1 and o.customer = ?2" ); query.setParameter( 1, 2 ); query.setParameter( 2, "John" ); List orders = query.getResultList(); … …
where条件表达式中可用的运算符基本上与SQL一致,包括:
算术运算符:+ - * / +(正) -(负) 关系运算符:== <> > >= < <= between…and like in is null 等
逻辑运算符: and or not
where子句示例:
下面是一些常见查询表达式示例:
// 以下语句查询 Id 介于 100 至 200 之间的订单。
select o from Orders o where o.id between 100 and 200
// 以下语句查询国籍为的 'US'、'CN'或'JP' 的客户。
select c from Customers c where c.county in ('US','CN','JP')
// 以下语句查询手机号以139开头的客户。%表示任意多个字符序列,包括0个。;
select c from Customers c where c.phone like '139%'
// 以下语句查询名字包含4个字符,且234位为ose的客户。_表示任意单个字符。
select c from Customers c where c.lname like '_ose'
// 以下语句查询电话号码未知的客户。Nul l用于测试单值是否为空。
select c from Customers c where c.phone is null
// 以下语句查询尚未输入订单项的订单。empty用于测试集合是否为空。
select o from Orders o where o.orderItems is empty
如果只须查询实体的部分属性而不需要返回整个实体。例如:
select o.id, o.customerName, o.address.streetNumber from Order o order by o.id
执行该查询返回的不再是Orders实体集合,而是一个对象数组的集合(Object[]),集合的每个成员为一个对象数组,可通过数组元素访问各个属性。
使用 Hibernate 的查询缓存
order by子句:order by子句用于对查询结果集进行排序。和SQL的用法类似,可以用 “asc“ 和 "desc“ 指定升降序。如果不显式注明,默认为升序。
select o from Orders o order by o.id
select o from Orders o order by o.address.streetNumber desc
select o from Orders o order by o.customer asc, o.id desc