Spring Data JPA渐进式学习--如何自定义查询方法呢?

1 定义查询方法的配置和使用方法

在Spring Data JPA中可以直接通过方法名实现CRUD

通过方法名实现CRUD

想要通过方法名实现CRUD的话,需要让我们的UserRepisitory继承CrudRepository,如下所示

public interface UserRepository extends CrudRepository<UserInfo,Integer> {

}

然后在service层就可以调用UserRepository里的方法了

选择性暴露CRUD方法

有时候我们不希望所有的方法都暴露出来,当有些数据只想被查看而不想被修改的时候,就可以如此。

具体操作就是,继承Repository类,自己写方法。

public interface UserRepository extends Repository<UserInfo,Integer> {
    UserInfo findOne();
    List<UserInfo> findAll();
}

这时在controller里调用的话,就只有这两个方法了。

2 方法的查询策略设置

通过@EnableJpaRepositories可以配置方法的查询策略,这个一般不会更改,默认的就可以。

@EnableJpaRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND)

这里可以选择的QueryLookupStrategy.Key的值共有三个

Create

Create 直接根据方法名进行创建,如UserInfo findByAgeAndName();会删除findBy字符,然后解析Age,And,Name.若是方法名不符合规则,则会报错。在这种策略模式下,配置了@Query也是没用的,只会解析方法名。

USE_DECLARED_QUERY

声明方式创建,这种策略模式下,必须配置Query,如下所示,并不会去解析方法名,

@Query("select u from UserInfo u")
UserInfo getAllList();

CREATE_IF_NOT_FOUND

这个则是以上两种情况的综合,会先去声明方式进行创建,若是没有,则解析方法名来创建一个查询。若是两者都不满足,则启动会报错。这是默认的查询策略

3 定义查询方法的语法

带查询功能的方法名由查询策略+查询字段+一些限制性条件语义清晰,功能完整。下表是DMQ语法常用的关键字列表。

再举一两个例子来说明一下。

//去重,and的用法
List<UserInfo> findDistinctByAddressAndName();

//根据name查找,并根据ID进行逆序排列
List<UserInfo> findByNameOrderByIdDesc();

虽然表中都是以find开头的,但是JPA还支持read,get,query,stream,count,exist,delete,remove等前缀,如字面意思一样使用即可。

4 特定类型的参数:Sort和Pageable

为了支持排序和分页,JPA支持了两个特殊类型的参数,Sort和Pageable。

Sort在查询的时候可以实现动态排序,并且决定了字段排序的方向。 Pageable可以实现分页和排序的双重效果。

接口定义方法与说明:

1 分页和总数

Page<UserInfo> findByName(String name, Pageable pageable);

这个返回将包含可用的元素和页面的总数,这个会默认执行一个count的语句,所以性能较低。

2 分页

Slice<UserInfo> findByName(String name, Pageable pageable);

返回结果是Slice,只查询结果不关心总数。

3 排序

List<UserInfo> findByName(String name, Sort sort);

只需要排序的时候可以这样操作,添加一个Sort参数即可。

4 排序和分页

List<UserInfo> findByName(String name, Pageable pageable);

这种情况下将只返回限制查询的结果,而其他的信息不做返回。

当在service层使用的时候,可以如下操作

//查询name是Luke的第一页,每页10个信息,并返回一共有多少页
Page<UserInfo> userList = userRepository.findByName("Luke",PageRequest.of(1,10));
//查询name是Luke的第一页的10条数据
Slice<UserInfo> userList = userRepository.findByName("Luke",PageRequest.of(1,10));
//查询name是Luke的数据,并按照age的逆序排列
List<UserInfo> userList = userRepository.findByName("Luke",new Sort(Sort.Direction.DESC,"age"));
//查询name是Luke的数据,取第一页的10条数据,并按照age的逆序排列
List<UserInfo> userList = userRepository.findByName("Luke",PageRequest.of(1,10,Sort.Direction.DESC,"age"));

5 限制查询结果:Fist和Top

当只想取前几天数据的时候,可以使用First和Top关键字。

举例说明

//按照name字段顺序排列,取第一个值
UserInfo findFirstByOrderByNameAsc();
//根据Id逆序排列并取第一个值
UserInfo findTopByOrderByIdDesc();
//排序后取前10个
List<UserInfo> findFirst10ByAge(Integer age,Sort sort);

值得注意的是:

  • 查询的时候可以在top和first后边跟数字表示需要多少个值。
  • 若是没有数字,默认就是1
  • 若是由Pageable参数,则以Top和First后边的数字为准
  • 也支持Distinct关键字

6 @NotNull @NonNullApi和@Nullable

@NotNull

用于不能为空的参数或者返回值

@NonNullApi

可以定义在包上,用于表示返回值的默认行为是不接受空值的

@Nullable

用于可以为空的参数或者返回值

以下代码表示,表示参数和返回值都可以是空了。

@Nullable
UserInfo findByName(@Nullable String n
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值