Spring Data JPA DMQ

380 阅读3分钟

1、什么是DMQ?

DMQ (Defining Query Method) 定义查询方法。若想要实现CRUD操作,无需再写一大堆SQL语句,直接通过方法名就可以实现查询,如下所示

public interface UserRepo extends CrudRepository<User,Integer>, PagingAndSortingRepository<User,Integer> , JpaRepository<User, Integer> {
    // 根据用户id和地址查询
    User findByIdAndAddress(int id,String address);
}

当不想暴露CrudRepository的所有方法时,我们可以自定义一个MyBaseRepository 然后继承Repository接口实现自己想要的方法,也可以选择SimpleJpaRepository中任意某个已经实现的方法。

public interface MyBaseRepo<T,ID extends Serializable> extends Repository<T,ID> {
    T findOne(ID id);

    T save(T entity);
}


public interface UserRepo extends MyBaseRepo<User,Integer> {
    User findByIdAndAddress(int id,String address);
}

2、方法的查询策略设置

为什么可以通过方法名或@Query也可以实现查询呢?

我们可以通过注解@EnableJpaRepositories可配置方法的查询策略

@EnableJpaRepositories(queryLookupStrategy = QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND)
  • Create:直接根据方法名进行创建。如果方法名不符合规则,启动的时候会报异常,这种情况可以理解为即使配置了@Query也是没用的
  • USE_DECLARED_QUERY:声明方式创建,可以理解为必须配置@Query。如果没有找到声明查询,将抛出一个异常。
  • CREATE_IF_NOT_FOUND:默认使用,兼容以上两种方式。先用声明方式(@Query)进行查找,如果没有找到与方法相匹配的查询,那就用Create的方法名创建规则来创建一个查询。如果都没有找到,启动就会报错。

3、定义查询方法的语法

语法: 查询策略(关键字)+ 查询字段 + 限制性条件

最重要的一点: 方法名的表达式通常是实体属性连接运算符的组合

image.png

3、特定类型的参数:Sort和Pageable

在上一文中我们介绍了Sort和Pageable在PageingAndSortingRepository接口中的使用。本文将会介绍Sort、Pageable在DMQ中的使用。

在DMQ中使用Sort和Pageable是非常简单的,直接作为参数传入到自定义方法中。

@Query(value = "FROM User u WHERE u.name LIKE ?1%")
List<User> findByNameLike(String name, Sort sort);

@Query(value = "FROM User u WHERE u.name LIKE ?1%")
List<User> findByNameLike(String name, Pageable pageable);

4、限制查询结果:First和Top

场景: 有的时候我们想直接查询前几条数据,也不需要动态排序,就可以简单地在方法名字中使用First和Top关键字,来限制返回条数

// 返回前三条数据
List<User> findTop3ByNameLike(String name);
// 返回前四条数据
List<User> findFirst4ByNameLike(String name);

注意:

  • 查询方法在使用First或Top时,数值可以追加到First或Top后面,指定返回最大结果的大小。
  • 如果数字被省略、则假设结果大小为1。
  • 如果将Pageable作为参数,以Top或First后面的数字为准,即分页将在限制结果中应用

5、@NonNUll、@NonNullApi 和 @Nullable 关键字

  • @NonNull:用于不能为空的参数或返回值
List<User> findTop3ByNameLike(@NonNull  String name);
  • @NonNullApi:在包级别用于声明参数,以及返回值的默认行为是不接受空值或产生空值的。

  • @Nullable: 用于可以为空的参数或返回值

@Nullable
List<User> findFirst4ByNameLike(String name);