3.SpringDataJPA之定义查询方法(接口规范和SQL注解)

开篇广告
自己开发的淘宝领券网站:q.hayye.cn(手机打开)
要说特色,应该没有,硬要说的话就是没广告、没推送,简单好用。
前端开源地址:https://gitee.com/hayye/tbq
后端不开源……
QQ群
欢迎大家加群讨论技术,不定时也会有淘宝神券发放!


正文开始

查询方法生成策略

Spring提供了三种查询方法生成策略query-lookup-strategy。可以在<jpa:repositories />标签中进行配置,可选值分别为:

create:通过解析方法名,由Spring创建查询方法;
use-declared-query:根据注解中定义好的查询语句进行查询;若找不到语句,则抛出异常;
create-if-not-found(默认):结合上两点,先查找是否有定义的查询语句,若没有,再根据方法名创建查询。

所以一般情况下,无需配置,使用默认的即可。

定义方法名查询

在接口中定义一个方法,但方法名要按照Spring规范定义,如此,Spring便可以自动生成对应的查询方法。
示例:

public interface BookRepository extends JpaRepository<Book,Long> {
    List<Book> findByBookname(String bookname);
    Page<Book> findByBooknameLike(String bookname,Pageable pageable);
}

该例中对应的JPQL分别为:

select b from book b where bookname = ?1;
select b from book b where bookname like ?1 limit  ?,?;

所以通过定义方法名的方式,可以实现大部分条件查询;

方法名规范:
  1. 前缀
    一共有九种前缀后加By,在org.springframework.data.repository.query.parser.PartTree中定义。
private static final String QUERY_PATTERN = "find|read|get|query|stream";
private static final String COUNT_PATTERN = "count";
private static final String EXISTS_PATTERN = "exists";
private static final String DELETE_PATTERN = "delete|remove";
  1. 属性名
    必须是该类中存在的属性,遵守驼峰命名法,且首字母大写,若实体内包含的实体属性需使用下划线隔开;
    例子:
    Person内的Address内的zipCode属性:findByAddress_ZipCode(String zipcode);
  2. 关键字
    例如Like、And、Between等、参考附表:查询方法关键字
注解式查询
@Query

注解形式的SQL、JPQL语句。注解常用参数如下:

value:SQL或JPQL语句;
nativeQuery:是否是SQL语句,默认false,即默认为JPQL语句;

实例:

public interface BookRepository extends JpaRepository<Book,Long> {
    @Query(value = "select b from Book b where b.bookname like %?1%")
    Page<Book> findByBooknameLike(String bookname , Pageable pageable);
    //支持@Param注解的写法
    @Query("select b from Book b where b.id = :id")
    Book findAllById(@Param("id")Long id);
}

默认JPQL模式下,是支持Sping提供的分页和排序方法的。在SQL模式下是不被支持的。
示例:

@Query(value = "select * from book where bookname like %?1% order by ?2 ",nativeQuery = true)
List<Book> findAllOrderBy(String bookname , String sort);
@Modifying

@Query注解只能用来查询数据,而不支持增、删、改;如果在@Query中使用insert、delete、update语句将会报错,解决办法就是@Modifying与@Query注解同时使用。

@Modifying
@Query(value = "DELETE FROM book where id = ?1 ",nativeQuery = true)
void deleteById(Long id);
@NamedQuery

预定义查询,由JPA提供,注解在实体类上,定义name和query即可。与Hibernate JPA用法稍有不同,参考以下例子:

  1. 在实体类上方声明预查询
@Entity
@NamedQuery(name = "Book.selectById",query = "select b from Book b where b.id = :id")
public class Book {
    ...
}
  1. 在BookRepository中对应方法
public interface BookRepository extends JpaRepository<Book,Long> {
    Book selectById(@Param("id")Long id);
}

之后就是调用了。

值得注意的是几种查询方法的优先级:@Query > @NamedQuery > 定义方法名查询


附:Demo源码 https://github.com/hayye/JPADemo

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值