【Spring Data 系列学习】Spring Data JPA @Query 注解查询
程序员文章站
2022-05-04 11:55:14
【Spring Data 系列学习】Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作。但同时 JPA 还提供通过注解的方式实现,通过将 注解在继承 repository 的接口类方法上 。 Qu ......
【spring data 系列学习】spring data jpa @query 注解查询
前面的章节讲述了 spring data jpa 通过声明式对数据库进行操作,上手速度快简单易操作。但同时 jpa 还提供通过注解的方式实现,通过将 @query
注解在继承 repository 的接口类方法上 。
query 源码讲解
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 ""; }
快速上手
项目中的pom.xml
、application.properties
与 chapter1 相同
实体类映射数据库表
user 实体类
@entity @table(name = "t_user") public class user implements serializable { private static final long serialversionuid = 1l; @id @generatedvalue(strategy = generationtype.identity) private long id; @column(name = "u_name") private string name; @column(name ="u_age") private integer age; @column(name ="u_email") private string email; // 省略构造器 set/get }
@entity
:定义对象将会成为被jpa管理的实体,将映射到指定的数据库表。
@table
:指定数据库的表名。
@column
:定义该属性对应数据库中的列名。
@id
定义属性为数据库的主键,一个实体里面必须有一个。
@generatedvalue(strategy = generationtype.identity)
自增长 id 策略
生成如下:
@query 查询
基本使用
继承 userqueryrepository
public interface userqueryrepository extends jparepository<user, long> { /** * 语句中 user 查询数据表的类名,?1 括号代表第一个参数 */ @query(name = "select * from user where name = ?1") list<user> findbyname(string name); /** * sort 排序 * 根据姓名模糊查询排序 */ @query("select u from user u where u.name like ?1%") list<user> findbyandsort(string name, sort sort); /** * @transactional 事务的支持 ,@modifying 用于修改查询 * @param name 对应 ?1 * @param id 对应 ?2 * @return */ @transactional @modifying @query("update user u set u.name = ?1 where u.id = ?2") int updatebyid(string name, long id); }
@param用法
/** * param 对象 * @param name * @param age * @return */ @query(value = "select u from user u where u.name = :name and u.age = :age") list<user> queryparambynameandage(@param("name") string name,@param("age") integer age); /** * 传一个对象 * @param user * @return */ @query(value = "select u from user u where u.name = :#{#user.name} and u.age = :#{#user.age}") list<user> queryobjectparambynameandage(@param("user") user user);
-
:name
对应@param
中的 name。 :age
对应@param
中的 age。:#{#user.name}
: 对象中的参数使用方法
spel表达式
@query("select u from #{#entityname} u where u.lastname = ?1") list<user> findbylastname(string lastname);
-
entityname
: 根据指定的 repository 自动插入相关的 entityname。有两种方式能被解析出来:- 如果定义了
@entity
注解,直接用其属性名。 - 如果没有定义,直接用实体类的名称。
- 如果定义了
原生 sql
@query(value = "select * from t_user where u_name = :name",nativequery = true) list<user> querynativebyname(@param("name") string name);
-
nativequery
: 为 true 开启。开启之后字段则需要对应的数据库中的表名和字段。
curd 测试类
路径:src/test/java/com/mtcarpenter/repository/userqueryrepositorytest.java
@runwith(springrunner.class) @springboottest public class userqueryrepositorytest { /** * ⽇志对象 */ private logger logger = loggerfactory.getlogger(userqueryrepositorytest.class); @autowired private userqueryrepository userqueryrepository; @before public void save() { logger.info("新增数据 result = {}", userqueryrepository.save(new user("小米", 9, "a@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("张三", 16, "b@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("三哥", 12, "c@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("米二", 13, "e@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("阿三", 12, "f@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("张三", 12, "g@qq.com"))); logger.info("新增数据 result = {}", userqueryrepository.save(new user("米二", 8, "h@qq.com"))); } /** * 基本使用 */ @test public void test() { logger.info("@query 查询张三 result = {}", userqueryrepository.findbyname("张三")); logger.info("根据姓名模糊查询排序 result = {}", userqueryrepository.findbynameandsort("米", new sort(sort.direction.asc,"age"))); logger.info("修改 id = 1 的name ,result ={ }", userqueryrepository.updatebyid("红米", 1l)); } /** * param 参数使用 */ @test public void paramtest(){ logger.info("@param 使用方法 result = {}",userqueryrepository.queryparambynameandage("张三", 12)); user user = new user(); user.setname("张三"); user.setage(12); logger.info("@param 对象 result = {}", userqueryrepository.queryobjectparambynameandage(user)); } /** * spel 使用 */ @test public void speltest(){ logger.info("spel 使用方法 result = {}",userqueryrepository.queryelbyname("张三")); } /** * 原生查询 */ @test public void nativetest(){ logger.info("原生查询 使用方法 result = {}",userqueryrepository.querynativebyname("张三")); } }
本章代码
- github:
推荐阅读
-
Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例
-
Spring Data JPA+kkpager实现分页功能实例
-
Spring Data JPA实现动态条件与范围查询实例代码
-
详解Spring Data JPA动态条件查询的写法
-
Spring boot中使用Spring-data-jpa方便快捷的访问数据库(推荐)
-
详解Spring Data Jpa 模糊查询的正确用法
-
Spring Data Jpa 复合主键的实现
-
Spring Data JPA 建立表的联合主键
-
使用Spring Data JPA的坑点记录总结
-
Spring Data Jpa 自动生成表结构的方法示例