JPA学习笔记(三):JPQL基本查询

概述

JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的对象化查询语言,JPQL是面向实体对象进行查询,而不是面向底层数据表查询,如:SELECT 属性名 FROM 类名。
JPQL它最终会被编译成 针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。
JPQL提供了Query接口,用于执行SELECT、UPDATE、DELETE操作。

// 查询所有员工信息
Query query = em.createQuery("select e from Employee e");
List emps = query.getResultList();
//查询id为3的员工信息
Query query2 = em.createQuery("select e from Employee e where empId = ?");
query2.setParameter(1, 3);
List emp = query2.getResultList();

//删除empId=3的员工信息
Query query = em.createQuery("delete from Employee where empId = ?");
query.setParameter(1, 3);
int update = query.executeUpdate();
System.out.println(update);

//修改empId为3的员工信息
Query query = em.createQuery("update Employee set userName = ?,age = ? where empId = ?");
query.setParameter(1, "小白");
query.setParameter(2, 20);
query.setParameter(3, 3);
int executeUpdate = query.executeUpdate();
System.out.println(executeUpdate);

Query接口

Query接口封装了执行数据库查询的相关方法。
调用 EntityManager 的 createQuery、create NamedQuery 及 createNativeQuery 方法可以获得Query查询对象,进而可调用 Query 对象的相关方法来执行查询操作。

  • createQuery(String jpql):用来执行JPQL语言查询。
  • createNamedQuery(String named):配合@NamedQuery注解使用, NamedQuery注解标注在实体类上,预先定义好JQPL语句,在参数列表中,通过参数名来引用预先声明的JPQL语句。
  • createNativeQuery(String sql):用来执行原生SQL查询语言。

SQL、JPQL语句中,可以定义 占位符 “?”,通过setParameter(m,n)方法进行占位填充即可。(m:占位符索引,从1开始,n:填充的值)

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 value, 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 value, TemporalType type) :为查询语句的指定位置参数赋 Calenda 赋值。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 异常。

JPQL查询语法

select语句用于执行查询。其语法可表示为:

select 属性 form 类 
[where 条件] 
[group by 属性]  [having 条件]
[order by 属性]

注意,JPQL是面向实体对象进行查询,SQL语句查询中,采用属性、类型进行查询。
可以使用关键字distinct修饰,表示不返回重复实体。
查询所有实体

select e from Employee as e     #as可以省略
from表示查询的实体类型,查询的名称与类名一致。

where子句

  • 该语句用来指定查询条件,条件字段与属性名一致。
  • 条件字段判断的值可以使用占位符“?”表示,也可以使用“:xxx”的参数化方式代替问号占位符,在查询前,通过setParameter(name,value)方式为参数赋值。
select e from Employee e where e.empId=:id and e.empName =:name
  • 也可以不使用参数名,而使用参数的序号,如:
select e from Employee e where e.empId=?1and e.empName =?2
query.setParameter( 1, 2 );
query.setParameter( 2, “xiaobai" );

where条件表达式中可用的运算符基本上与SQL一致,包括:

算术运算符:+ - * / +(正) -(负)
关系运算符:== <> > >= < <= between…and like in is null 等
逻辑运算符: and or  not

示例:

select e from Employee e where e.empId between 1 and 10
select e from Employee e where e.age in (18,19,20)
select e from Employee e where e.phone like '166%'
select e from Employee e where e.lastName like ‘%li%' 
select e from Employee e where e.dept is null
select d from  Dept d where d.emps is empty

投影查询:如只须查询实体的部分属性而不需要返回整个实体。如:

select e.empId, e.lastName, e.dept.deptName from Employee e order by e.age

该查询语句结果返回的不再是Employee实体对象集合,而是一个对象数组的集合List,每一个集合成员为Object[],对应一条查询记录。

select e.empId,e.lastName from Employee e;

可以在实体类中定义与查询字段对应的构造方法,在JPQL语句中使用new 实体类 的方式进行转换。
在这里插入图片描述
查询缓存
通过如下方式设置,可以让当前Query支持查询缓存:

query.setHint(QueryHints.CACHEABLE,false);

order by子句用于对查询结果集进行排序。
asc:升序,默认选项;
desc:降序;

select e from Employee e order by e.empId

group by 子句用于对查询结果分组统计,通常需要使用聚合函数。常用的聚合函数主要有 AVG、SUM、COUNT、MAX、MIN 等,它们的含义与SQL相同。
使用聚合函数将返回单个结果值,可以使用Query.getSingleResult()得到查询结果。例如:

Query query = entityManager.createQuery("select max(e.age) from Employee e");
Object result = query.getSingleResult();
Long max = (Long)result;

Having 子句用于对 group by 分组查询后的结果进行过滤。

  • 用法与where 子句基本相同,不同是 where 子句作用于基表或视图,以便从中选择满足条件的记录;having 子句则作用于分组,用于选择满足条件的组,其条件表达式中通常会使用聚合函数。
  • 如:查询部门员工人数大于10个的部门:
select dept.deptName,count(dept.deptName) from Dept dept group by dept.deptName having count(dept.deptName) >10;

更多文章

你可能感兴趣的:(JPA,笔记)