Jpa:JPQL(三)
文章目录
- 查询
- 1.二级缓存
- 2.JPQL
- 2.1 介绍
- 2.2 javax.persistence.Query
- 2.3 select语法
- 2.4查询所有实体
- 2.5 where
- 2.6 查询部分属性
- 2.7 order by
- 2.8 group by
- 2.9 Having
- 2.10 关联查询
- 2.11 子查询
- 2.12 JPQL函数
- 3.与Spring整合
查询
1.二级缓存
节点:若 JPA 实现支持二级缓存,该节点可以配置在当前的持久化单元中是否启用二级缓存,可配置如下值:
- ALL:所有的实体类都被缓存
- NONE:所有的实体类都不被缓存.
- ENABLE_SELECTIVE:标识 @Cacheable(true) 注解的实体类将被缓存
- DISABLE_SELECTIVE:缓存除标识 @Cacheable(false) 以外的所有实体类
- UNSPECIFIED:默认值,JPA 产品默认值将被使用
@Testpublic void testSecondLevelCache(){//若是同一个manager,则查询时,是相同的,则只执行一个查询Person person3 = entityManager.find(Person.class, 27);Person person4 = entityManager.find(Person.class, 27);//若不是同一个managerPerson person = entityManager.find(Person.class, 27);transaction.commit();entityManager.close();//当重新获取一个manager后,再执行查询,则sql会再次执行entityManager = entityManagerFactory.createEntityManager();transaction = entityManager.getTransaction();transaction.begin();Person person2 = entityManager.find(Person.class, 27);}
参考:
JPA-二级缓存
2.JPQL
2.1 介绍
JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。
JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query 接口封装执行
2.2 javax.persistence.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 异常。
2.3 select语法
select语句用于执行查询。其语法可表示为:
select_clause
form_clause
[where_clause]
[groupby_clause]
[having_clause]
[orderby_clause]
@Testpublic void testHelloJPQL(){String jpql = "FROM Person p WHERE p.pid > ?";Query query = entityManager.createQuery(jpql);//占位符的索引是从 1 开始query.setParameter(1, 27);List<Person> personList = query.getResultList();System.out.println(personList.size());}
2.4查询所有实体
- 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
}
2.5 where
where子句用于指定查询条件,where跟条件表达式。例:select o from Orders o where o.id = 1select 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 = :myIdselect 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例如:
下面是一些常见查询表达式示例:
// 以下语句查询 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… …
2.6 查询部分属性
如果只须查询实体的部分属性而不需要返回整个实体。例如:
select o.id, o.customerName, o.address.streetNumber from Order o order by o.id
执行该查询返回的不再是Orders实体集合,而是一个对象数组的集合(Object[]),集合的每个成员为一个对象数组,可通过数组元素访问各个属性。
2.7 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
2.8 group by
group by 子句用于对查询结果分组统计,通常需要使用聚合函数。常用的聚合函数主要有 AVG、SUM、COUNT、MAX、MIN 等,它们的含义与SQL相同。例如:
select max(o.id) from Orders o
没有 group by 子句的查询是基于整个实体类的,使用聚合函数将返回单个结果值,可以使用Query.getSingleResult()得到查询结果。例如:
Query query = entityManager.createQuery("select max(o.id) from Orders o");
Object result = query.getSingleResult();
Long max = (Long)result;
2.9 Having
Having 子句用于对 group by 分组设置约束条件,用法与where 子句基本相同,不同是 where 子句作用于基表或视图,以便从中选择满足条件的记录;having 子句则作用于分组,用于选择满足条件的组,其条件表达式中通常会使用聚合函数。
例如,以下语句用于查询订购总数大于100的商家所售商品及数量:
select o.seller, o.goodId, sum(o.amount) from V_Orders o group by
o.seller, o.goodId having sum(o.amount) > 100
having子句与where子句一样都可以使用参数。
2.10 关联查询
在JPQL中,很多时候都是通过在实体类中配置实体关联的类属性来实现隐含的关联(join)查询。例如:
select o from Orders o where o.address.streetNumber=2000
上述JPQL语句编译成以下SQL时就会自动包含关联,默认为左关联。
在某些情况下可能仍然需要对关联做精确的控制。为此,JPQL 也支持和 SQL 中类似的关联语法。如:
left out join / left join
inner join
left join / inner join fetch
其中,left join和left out join等义,都是允许符合条件的右边表达式中的实体为空。例如,以下外关联查询可以找出所有客户实体记录,即使它未曾订货:
select c from Customers c left join c.orders o
以下内关联查询只找出所有曾订过商品的客户实体记录:
select c from Customers c inner join c.orders o
如果001号客户下过5次订单的话,以下fetch关联查询将得到 5个客户实体的引用,并且执行了 5 个订单的查询:
select c from Customers c left join fetch c.orders o where c.id=001
2.11 子查询
JPQL也支持子查询,在 where 或 having 子句中可以包含另一个查询。当子查询返回多于 1 个结果集时,它常出现在 any、all、exist s表达式中用于集合匹配查询。它们的用法与SQL语句基本相同。
2.12 JPQL函数
JPQL提供了以下一些内建函数,包括字符串处理函数、算术函数和日期函数。
字符串处理函数主要有:
concat(String s1, String s2):字符串合并/连接函数。
substring(String s, int start, int length):取字串函数。
trim([leading|trailing|both,] [char c,] String s):从字符串中去掉首/尾指定的字符或空格。
lower(String s):将字符串转换成小写形式。
upper(String s):将字符串转换成大写形式。
length(String s):求字符串的长度。
locate(String s1, String s2[, int start]):从第一个字符串中查找第二个字符串(子串)出现的位置。若未找到则返回0。
3.与Spring整合
三种整合方式:
- LocalEntityManagerFactoryBean:适用于那些仅使用 JPA 进行数据访问的项目,该 FactoryBean 将根据JPA PersistenceProvider 自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息,这种方式最简单,但不能设置 Spring 中定义的DataSource,且不支持 Spring 管理的全局事务
- 从JNDI中获取:用于从 Java EE 服务器获取指定的EntityManagerFactory,这种方式在进行 Spring 事务管理时一般要使用 JTA 事务管理
- LocalContainerEntityManagerFactoryBean:适用于所有环境的 FactoryBean,能全面控制 EntityManagerFactory 配置,如指定 Spring 定义的 DataSource 等等。
Jpa:JPQL(三)相关推荐
- 007_Spring Data JPA JPQL
1. JPQL基于@Query注解的查询 1.1. JPQL是通过Hibernate的HQL演变过来的, 它和HQL语法及其相似. 1.2. 因为Hibernate的HQL语言是用于面向对象实现查询功 ...
- jPA jpql
JPQL就是一种查询语言,具有与 SQL 相类似的特征, JPQL 是完全面向对象的,具备继承.多态和关联等特性,和hibernate HQL很相似. 查询语句的参数 JPQL 语句支持两种方式的参数 ...
- JPA(三)之实体关系一对多(多对一)
1.背景介绍: 对于购买商品时,订单信息(Order)和订单商品信息(OrderItem)的关系就是一对多的关系. 2.实体bean: Order.java代码 ? 1 2 3 4 5 6 7 ...
- springdata jpa jpql 条件查询
jpql 条件为真,则添加条件查询:否则不添加条件查询: 参数是否为空,是则添加参数条件,否不添加 @Query(value="select eva.id as id,eva.userTyp ...
- Spring Hibernate JPA 联表查询 复杂查询
(转自:http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html) 今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的 ...
- 【转】JPA、Hibernate和Mybatis区别和总结
很多人都用过java的数据库连接池C3P0,但官方没有说明名称的由来. 据传闻:连接池作者是<星球大战>迷,C3P0就是其中的一个机器人,并且这个名称中包涵connection 和pool ...
- Java开发必看JPA概念大全
一.JPA简介 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. [1 ...
- jpa 定义中间表实体_JPA系列之-带你快速掌握JPA
课程目录: 课程目标:理解JPA规范,JPA提供商,JPA的优势,JPA的具体开发应用.JPA是SUN公司定义的持久化API,相当于JDBC的角色,以统一的接口访问数据库,通过本课程的学习,让大家快速 ...
- 【JDBC】JPA和JDBC的区别
1. 引言 在介绍JPA和JDBC之前,我们先了解一个概念: 持久化: 将程序数据在持久状态和瞬时状态间转换的机制.通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持 ...
最新文章
- AI让硬件说话,这就是未来物联网
- python中isinstance(3、object)_Python中为什么推荐使用isinstance来进行类型判断?而不是type...
- 函数:使用递归实现阶乘
- 重写系统自带tabbar出现的 代理错误
- 用SAPI实现Speech Recognition(SR) - 命令控制模式
- python多线程用法及与单线程耗时比较
- Linux命令之hexdump
- 中山大学提出新型行人重识别方法和史上最大评测基准
- mysql 查询列表是否关注_点赞功能,用mysql还是redis?
- 面试时如何在众多Java工程师中脱颖而出
- 获取高德POI(关键词搜索法 多边形搜索法 周边搜索法)综合运用 2022新版高德poi下载
- 数学分析-换底公式证明
- 关于网站推广 网站营销 建议
- 如何屏蔽谷歌浏览器的账号密码自动填充和账号密码选择
- 简单的视频压缩大小技巧来了,小白也能轻松上手
- AI测试】人工智能测试整体介绍——第五部分
- 操作系统存储器管理管理试验
- mysql数据库管理-innode undo表空间
- 时尚育儿观:情商第一 智商第二
- Spark Jdbc报NullPointerException
热门文章
- Instagram的技术架构
- 我的Android进阶之旅】GitHub 上排名前 100 的 Android 开源库进行简单的介绍
- 调侃《HeadFirst设计模式》之观察者模式
- 计算机视觉大牛代季峰从商汤离职,加入清华电子系
- excel提示:输入值非法,其他用户已经限定了可以输入该单元格的数值
- python - input()用户输入的值不合法则要求重新输入
- SSH神器Tabby链接Ubuntu
- Unsafe.compareAndSwapInt()方法解读
- 荣耀9x支持升级鸿蒙吗,华为为老机型续命,荣耀9X被爆升级鸿蒙2.0,4GB内存还能再战?...
- 会议技术发展与高清视频会议系统