简介

JPQL语言,即 Java Persistence Query Language 的简称。JPQL 是一种和 SQL 非常类似的中间性和对象化查询语言,它最终会被编译成针对不同底层数据库的 SQL 查询,从而屏蔽不同数据库的差异。
JPQL语言的语句可以是 select 语句、update 语句或delete语句,它们都通过 Query 接口封装执行

接口

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

方法

  1. setHint(String hintName, Object value)

设置与查询对象相关的特定供应商参数或提示信息。参数名及其取值需要参考特定 JPA 实现库提供商的文档。如果第二个参数无效将抛出IllegalArgumentException异常。

  1. setParameter(int position, Object value)

为查询语句的指定位置参数赋值。Position 指定参数序号,从1开始,value 为赋给参数的值。

  1. 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)。

  1. setParameter(int position, Calendar value, TemporalType type)

为查询语句的指定位置参数赋 Calendar值。position 指定参数序号,value 为赋给参数的值,temporalType 的含义及取舍同前。

  1. setParameter(String name, Object value)

为查询语句的指定名称参数赋值。

  1. setParameter(String name, Date value, TemporalType type)

为查询语句的指定名称参数赋 Date 值。用法同前。

  1. setParameter(String name, Calendar value, TemporalType type)

为查询语句的指定名称参数设置Calendar值。name为参数名,其它同前。该方法调用时如果参数位置或参数名不正确,或者所赋的参数值类型不匹配,将抛出 IllegalArgumentException 异常。

  1. int executeUpdate()

用于执行update或delete语句。

  1. List getResultList()

用于执行select语句并返回结果集实体列表。

  1. Object getSingleResult()

用于执行只返回单个结果实体的select语句。

  1. Query setFirstResult(int startPosition)

用于设置从哪个实体记录开始返回查询结果。

  1. Query setMaxResults(int maxResult)

用于设置返回结果实体的最大数。与setFirstResult结合使用可实现分页查询。

  1. Query setFlushMode(FlushModeType flushMode)

设置查询对象的Flush模式。参数可以取2个枚举值:FlushModeType.AUTO 为自动更新数据库记录,FlushMode Type.COMMIT 为直到提交事务时才更新数据库记录。

查询

1 createQuery

  1. @Test
  2. public void testHelloJPQL() {
  3. String jpql = "from Customer c where c.age > ?1";
  4. Query query = entityManager.createQuery(jpql);
  5. query.setParameter(1, 12);
  6. List<Customer> customers = query.getResultList();
  7. System.out.println(customers.size());
  8. }

2 createNamedQuery

需要在实体类上面加上注解NamedQuery(name = “testNamedQuery”, query = “select c from Customer c where c.id = ?”)

  1. // createNamedQuery 适用于实体类前使用@NameQuery标记的查询语句
  2. @Test
  3. public void testNameQuery() {
  4. Query query = entityManager.createNamedQuery("testNameQuery").setParameter(1, 3);
  5. Customer customer = (Customer) query.getSingleResult();
  6. System.out.println(customer);
  7. }

3 createNativeQuery

  1. // createNativeQuery 适用于本地sql
  2. @Test
  3. public void testNativeQuery() {
  4. String sql = "select age From jpa_cutomers where id > ?";
  5. Query query = entityManager.createNativeQuery(sql).setParameter(1, 15);
  6. Object result = query.getSingleResult();
  7. System.out.println(result);
  8. }

4 查询缓存

  1. // 使用hibernate的查询缓存 前提:配置中要启用查询缓存
  2. @Test
  3. public void testQueryCache() {
  4. String jpql = "from Customer c where c.age > ?";
  5. Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);
  6. query.setParameter(1, 12);
  7. List<Customer> customers = query.getResultList();
  8. System.out.println(customers.size());
  9. query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);
  10. query.setParameter(1, 12);
  11. customers = query.getResultList();
  12. System.out.println(customers.size());
  13. }

5 OrderBy

  1. public void testOrderBy() {
  2. String jpql = "from Customer c where c.age > ? order by c.age desc";
  3. Query query = entityManager.createQuery(jpql);
  4. query.setParameter(1, 12);
  5. List<Customer> customers = query.getResultList();
  6. System.out.println(customers.size());
  7. }

6 GroupBy

  1. // 查询order 数量大于2的那些customer
  2. @Test
  3. public void testGroupBy() {
  4. String jpql = "select o.customer from Order o group by o.customer having count(o.id) > 2";
  5. List<Customer> customers = entityManager.createQuery(jpql).getResultList();
  6. System.out.println(customers);
  7. }

7 关联查询

  1. public void testLeftOuterJoinFetch() {
  2. // left outer join fetch 返回的是对象
  3. String jpql = "from Customer c left outer join fetch c.orders where c.id = ?";
  4. Customer customer = (Customer) entityManager.createQuery(jpql).setParameter(1, 14).getSingleResult();
  5. System.out.println(customer);
  6. System.out.println(customer.getOrders().size());
  7. // left outer join 返回的是Object[]
  8. String jpql = "from Customer c left outer join c.orders where c.id = ?";
  9. List<Object[]> result = entityManager.createQuery(jpql).setParameter(1, 14).getResultList();
  10. System.out.println(result);
  11. }

8 子查询

  1. // 子查询 查询所有Customer的lastName为yy的order
  2. @Test
  3. public void testSubQuery(){
  4. String jpql = "select o from Order o where o.customer = (select c from Customer c where c.lastName = ?)";
  5. List<Order> orders = entityManager.createQuery(jpql).setParameter(1, "YY").getResultList();
  6. System.out.println(orders.size());
  7. }

9 函数

•字符串处理函数主要有:
–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。
•算术函数主要有 abs、mod、sqrt、size 等。Size 用于求集合的元素个数。
•日期函数主要为三个,即 current_date、current_time、current_timestamp,它们不需要参数,返回服务器上的当前日期、时间和时戳。

10 update操作

  1. // delete与update同
  2. @Test
  3. public void testExecuteUpdate(){
  4. String jpql = "update Customer c set c.lastName = ? where c.id = ?";
  5. Query query = entityManager.createQuery(jpql);
  6. query.setParameter(1,"YYY");
  7. query.setParameter(2,13);
  8. query.executeUpdate();
  9. }