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


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

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

    通过方法名实现CRUD

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

    1. public interface UserRepository extends CrudRepository<UserInfo,Integer> {
    2. }

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

    选择性暴露CRUD方法

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

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

    1. public interface UserRepository extends Repository<UserInfo,Integer> {
    2. UserInfo findOne();
    3. List findAll();
    4. }

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

    2 方法的查询策略设置

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

    1. @EnableJpaRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND)

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

    Create

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

    USE_DECLARED_QUERY

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

    1. @Query("select u from UserInfo u")
    2. UserInfo getAllList();

    CREATE_IF_NOT_FOUND

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

    3 定义查询方法的语法

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

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

    1. //去重,and的用法
    2. List<UserInfo> findDistinctByAddressAndName();
    3. //根据name查找,并根据ID进行逆序排列
    4. List<UserInfo> findByNameOrderByIdDesc();

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

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

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

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

    接口定义方法与说明:

    1 分页和总数

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

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

    2 分页

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

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

    3 排序

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

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

    4 排序和分页

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

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

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

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

    5 限制查询结果:Fist和Top

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

    举例说明

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

    值得注意的是:

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

    6 @NotNull @NonNullApi和@Nullable

    @NotNull

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

    @NonNullApi

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

    @Nullable

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

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

    1. @Nullable
    2. UserInfo findByName(@Nullable String n
  • 相关阅读:
    ES实战系列-Elasticsearch介绍
    juc详解
    Spring——三级缓存解决循环依赖详解
    js事件循环EventLoop
    《深度探索C++对象模型》阅读笔记 第七章 站在对象模型的尖端
    CSAPP Lab5:Shell
    零成本体验美国云服务器,更方便的体验和选择
    Unirech腾讯云代充-云服务器登陆及远程连接常见问题
    电脑mp4格式视频打不开怎么解决?
    从0到1搞定前端性能测试(非常详细)
  • 原文地址:https://blog.csdn.net/LBWNB_Java/article/details/126776466