Spring Data JPA查询方式及方法名查询规则

Spring Data JPA

一、通过解析方法名创建查询

 

在执行查询时,Spring Data JPA框架会把方法名进行解析,解析到前缀比如 get、getBy、find、findBy、read、readBy时,会先把这些前缀截取掉,然后对剩下部分进行解析,剩下部分分为两种:一是只有属性名,二是属性名+条件;条件很好解析,解析的关键在于属性名,下面拿一个具体的例子来帮助大家更好的理解属性名解析规则。

解析规则例子:比如实体为Product,方法为findByGoodsTypeDetail ();

一、首先截取掉 findBy,然后对剩下的属性进行解析;

二、先判断 goodsTypeDetail(根据 POJO 规范,首字母变为小写,下同)是否为 Product的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第三步;
三、从右往左截取第一个大写字母开头的字符串(本方法为 Detail),然后对比剩下的字符串(本方法为goodsType)是否为 Product的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第三步,继续从右往左截取(此处为TypeDetail,剩下goods),就这样一直循环到最终;假设 goods为 Product的一个属性,则说明goods不是常量类型,而是一个对象类型;

四、此时剩下字符串 TypeDetail,先判断goods对象中是否有 typeDetail属性,如果有,则表示该方法最终是根据 "Product.goods.typeDetail" 的值进行查询;如果没有该属性,则继续按照第三步的规则从右往左截取,最终表示根据 "Product.goods.type.detail" 的值进行查询。

不过这种解析规则不是完美的,也存在bug,不注意可能会掉到这个坑里,比如Product中有一个属性叫goods,同时还有一个属性叫goodsType,这时在解析时会出现混乱,不过可以在属性之间加上 "_"来解决这个问题,注意:"_"是加在查询方法上的,不是加在属性名上的;比如 "findByGoods_TypeDetail()" (当Product中不存在goods_TypeDetail时,是给解析器说明Goods为一个对象)或"findByGoodsType_Detail()"(当Product中不存在goodsType_Detail时,是给解析器说明GoodsType为一个对象)。

查询时,很多时候需要同时使用多个属性进行查询,而且查询的条件也各不相同,Spring Data JPA 为此提供了一些条件查询的关键字,我把常用的都整理了一下,如下表:

关键字

对应SQL关键字

示例

列名

根据列名查询

findByName(String name);自动解析findBy后面的列名,然后根据列名查询。

In

等价于SQL 中的 in

findByNameIn(Collection<String> nameList) ;参数可以是集合、数组、不定长参数;

Like

等价于SQL 中的 like

findByNameLike(String name);

NotLike 等价于SQL 中的 not like findByNameNotLike(String name);

And

等价于SQL 中的 and

findByNameAndPwd(String name, String pwd);

Or

等价于SQL 中的 or

findByIdOrCode(String id, String code);

Between

等价于SQL 中的 between

findByNumBetween(int max, int min);

OrderBy

等价于SQL 中的 order by

findByNameOrderByNumAsc(String name);

IsNull

等价于SQL 中的 is null

findByNameIsNull();

IsNotNull 等价于SQL 中的 is not null findByNameIsNotNull();
NotNull 等价于SQL 中的 is not null findByNameNotNull();--和IsNotNull 一样,建议使用IsNotNull
Not 等价于SQL 中的 ! = findByNameNot(String name);
NotIn 等价于SQL 中的 not in findByNameNotIn(Collection<String> nameList) ;参数可以是集合、数组、不定长参数;
LessThan 等价于SQL 中的 < findByNumLessThan(int num);

GreaterThan

等价于SQL 中的 >

findByNumGreaterThan(int num);

二、使用 @Query 创建查询


一、使用 @Query 提供的位置编号查询:格式为":位置编号",然后方法中的参数按 JPQL 查询语句的位置编号顺序书写。     如下:

public interface ProductDao extends Repository<Product , Long> { 
 
@Query("select p from Product p where p.id= ?1") 
public Product findById(Long id); 
 
@Query("select p from Product p where p.type = ?1 and p.name =?2") 
public Page<Product> findByTypeAndName( 
    Integer type,String name,Pageable pageable); 
}


二、使用@Query 命名参数查询:格式为": 变量",同时在方法的参数前面使用 @Param 将方法参数与JPQL中的命名参数对应。如下:

public interface ProductDao extends Repository<Product , Long> { 
 
@Query("from Product p where p.goodsName= :name") 
public Product findByGoodsName(@Param("name")String name); 
 
@Query("from Product p where p.num < :num") 
public Page<Product> findByNumLessThan( 
    @Param("num")Integer num,Pageable pageable); 
}


三、 使用 @Modifying 将查询操作标识为更新操作:在使用 @Query 的同时使用 @Modifying ,这样会生成一个更新的操作,而非查询。如下:


@Query("update Product p set p.name = ?1 where p.id = ?2") 
@Modifying 
public int updateName(String name, int id);
发布了74 篇原创文章 · 获赞 53 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/m0_37679452/article/details/83278000