语法及其源码

public @interface Query {/*** 指定JPQL的查询语句。(nativeQuery=true的时候,是原生的Sql语句)*/String value() default "";/*** 指定count的JPQL语句,如果不指定将根据query自动生成。* (如果当nativeQuery=true的时候,指的是原生的Sql语句)*/String countQuery() default "";/*** 根据哪个字段来count,一般默认即可。*/String countProjection() default "";/*** 默认是false,表示value里面是不是原生的sql语句*/boolean nativeQuery() default false;/*** 可以指定一个query的名字,必须唯一的。* 如果不指定,默认的生成规则是:* {$domainClass}.${queryMethodName}*/String name() default "";/** 可以指定一个count的query的名字,必须唯一的。* 如果不指定,默认的生成规则是:* {$domainClass}.${queryMethodName}.count*/String countName() default "";
}

@Query 用法

使用命名查询为实体声明查询是一种有效的方法,对于少量查询很有效。一般只需要关心 @Query 里面的 value 和 nativeQuery 的值。使用声明式 JPQL 查询有个好处,就是启动的时候就知道你的语法正确不正确。

注意:好的架构师写代码时报错的顺序是编译<启动<运行时,即越早发现错误越好。默认 value 里面是 JPQL 语法,既对象查询和 SQL、HQL 比较类似。

案例 4.1:声明一个注解在 Repository 的查询方法上。

public interface UserRepository extends JpaRepository<User, Long>{@Query("select u from User u where u.emailAddress = ?1")User findByEmailAddress(String emailAddress);
}

案例 4.2:Like 查询,注意 firstname 不会自动加上 % 关键字。

public interface UserRepository extends JpaRepository<User, Long> {@Query("select u from User u where u.firstname like %?1")List<User> findByFirstnameEndsWith(String firstname);
}

案例 4.3:直接用原始 SQL。

public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)User findByEmailAddress(String emailAddress);
}

注意:nativeQuery 不支持直接 Sort 的参数查询。

案例4.4:nativeQuery 的排序错误的写法,下面这个是启动不起来的。

public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "select * from user_info where first_name=?1",nativeQuery = true)
List<UserInfoEntity> findByFirstName(String firstName,Sort sort);
}

案例4.5:nativeQuery 排序的写法。

@Query(value = "select * from user_info where first_name=?1 order by ?2",nativeQuery = true)
List<UserInfoEntity> findByFirstName(String firstName,String sort);
//调用的地方写法last_name是数据里面的字段名,不是对象的字段名
repository.findByFirstName("jackzhang","last_name");

@Query 的排序

@Query 的 JPQL 情况下,想实现排序,方法上面直接用 PageRequest 或者直接用 Sort 参数都可以做到。

在排序实例中实际使用的属性需要与实体模型里面的字段相匹配,这意味着它们需要解析为查询中使用的属性或别名。这是一个state_field_path_expression JPQL定义,并且 Sort 的对象支持一些特定的函数。

案例 4.6:Sort and JpaSort 的使用。

public interface UserRepository extends JpaRepository<User, Long> {@Query("select u from User u where u.lastname like ?1%")List<User> findByAndSort(String lastname, Sort sort);@Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
//调用方的写法,如下:
repo.findByAndSort("lannister", new Sort("firstname"));
repo.findByAndSort("stark", new Sort("LENGTH(firstname)"));
repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)"));
repo.findByAsArrayAndSort("bolton", new Sort("fn_len")); 

@Query 的分页

案例 4.7:直接用 Page 对象接受接口,参数直接用 Pageable 的实现类即可。

public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "select u from User u where u.lastname = ?1")Page<User> findByLastname(String lastname, Pageable pageable);
}
//调用者的写法
repository.findByFirstName("jackzhang",new PageRequest(1,10));

案例 4.8:对原生 SQL 的分页支持,案例如下,但是支持的不是特别友好,以 MySQL 为例。

 public interface UserRepository extends JpaRepository<UserInfoEntity, Integer>, JpaSpecificationExecutor<UserInfoEntity> {@Query(value = "select * from user_info where first_name=?1 /* #pageable# */",countQuery = "select count(*) from user_info where first_name=?1",nativeQuery = true)Page<UserInfoEntity> findByFirstName(String firstName, Pageable pageable);
}
//调用者的写法
return userRepository.findByFirstName("jackzhang",new PageRequest(1,10, Sort.Direction.DESC,"last_name"));
//打印出来的sql
select  *   from  user_info  where  first_name=? /* #pageable# */  order by  last_name desc limit ?, ?

注意:

  • 这个注释 /* #pageable# */ 必须有;
  • 估计有可能随着版本的变化这个会做优化。
  • 另外一种实现方法就是自己写两个查询方法,自己手动分页。

Spring Data JPA 从入门到精通~@Query详解相关推荐

  1. Spring Data JPA 从入门到精通~@Version处理乐观锁的问题

    @Version 处理乐观锁的问题 @Version 乐观锁介绍 我们在研究 Auditing 的时候,发现了一个有趣的注解 @Version,源码如下: package org.springfram ...

  2. spring data jpa从入门到精通_Spring Data JPA的简单入门

    前言 spring data JPA是spring团队打造的sping生态全家桶的一部分,本身内核使用的是hibernate核心源码,用来作为了解java持久层框架基本构成的样本是再好不过的选择.最近 ...

  3. Spring Data JPA 从入门到精通~实际工作的应用场景

    在实际工作中,有哪些场景会用到自定义 Repository 呢,这里列出几种实际在工作中的应用案例. 1. 逻辑删除场景 可以用到上面说的两种实现方式,如果有框架级别的全局自定义 Respositor ...

  4. Spring Data JPA 从入门到精通~自定义实现Repository

    EntityManager 的获取方式 我们既然要自定义,首先讲一下 EntityManager 的两种获取方式. 1. 通过 @PersistenceContext 注解. 通过将 @Persist ...

  5. Spring Data JPA 从入门到精通~EntityManager介绍

    EntityManager 介绍 我们前面已经无数次提到了,JPA 的默认 Repository 的实现类是 SimpleJpaRepository,而里面的具体实现就是调用的 EntityManag ...

  6. Spring Data JPA 从入门到精通~JpaSpecificationExecutor示例

    新建两个实体 @Entity(name = "UserInfoEntity") @Table(name = "user_info", schema = &quo ...

  7. Spring Data JPA 从入门到精通~JpaSpecificationExecutor的使用方法

    JpaSpecificationExecutor 源码和 API 我们也可以通过 idea 工具详细看其用法和实现类,JpaSpecificationExecutor 是 Repository 要继承 ...

  8. Spring Data JPA 从入门到精通~QueryByExampleExecutor的使用

    QueryByExampleExecutor 的使用 按示例查询(QBE)是一种用户友好的查询技术,具有简单的接口,它允许动态查询创建,并且不需要编写包含字段名称的查询.从 UML 图中,可以看出继承 ...

  9. Spring Data JPA 从入门到精通~javax.persistence概况介绍

    虽然 Spring Data JPA 已经对数据的操作封装的很好了,约定大于配置的思想,帮我们默认了很多东西.JPA(Java 持久性 API)是存储业务实体关联的实体的来源,它显示了如何定义一个面向 ...

最新文章

  1. 一分钟在Linux环境下创建一台SFTP服务器(含账户创建)
  2. HttpServletRequest和HttpServletResponse简介
  3. win2003 + sqlserver2K sp4,客户端无法连接
  4. 深度学习:tensorflow的简单用法,tensorflow实现SVM
  5. DJ轮回舞曲网下载教程
  6. Unity 下载存档
  7. Fiddler跨域调试及Django跨域处理
  8. LeetCode刷题——345. 反转字符串中的元音字母
  9. linux hg(mercurial)入门
  10. python正则表达式面试题,带有utf8问题的python正则表达式
  11. JAVAEE框架架构高级视频教程
  12. 三星入职测试GSAT(global samsung aptitude test)
  13. 嵌入式linux gps,嵌入式Linux平台的GPS数据采集
  14. 一文教你玩转Mybatis,超详细代码讲解与实战
  15. 3D变形:平移、旋转、缩放
  16. Faster RCNN超详细入门 02 网络细节与训练方法
  17. 苹果手机数据线充不了电_深圳苹果手机数据线多少钱一条
  18. 新中新二代身份证读卡器C#开发问题及解决方法
  19. 原始设备制造商OEM简介
  20. Google面试官亲授Java面试课程

热门文章

  1. Android自动化页面测速在美团的实践
  2. 论文浅尝 - ACL2020 | 用于关系三元组抽取的级联二进制标记框架
  3. 论文浅尝 | 利用知识图谱嵌入和图卷积网络进行长尾关系抽取
  4. 论文浅尝 | AMUSE: 基于 RDF 数据的多语言问答语义解析方法
  5. 领域应用 | 深度学习在知识图谱构建中的应用
  6. PDFPlumber使用入门+python实现PDF中表格转化为Excel的方法
  7. [模板]洛谷T3379 最近公共祖先(LCA) 倍增+邻接表
  8. VVDocumenter 使用
  9. log4j的配置方法
  10. burp的intruder报错Payload set 1: Invalid number settings