JPQL空值过滤查询时为name、surname字段添加LIKE模糊匹配的实现问询
实现JPQL模糊匹配的修改方案
你需要先修正现有代码的两处隐患,再调整查询逻辑即可实现需求:
1. 修正包装类的基本类型定义
你当前ProductWrapper中的quantity、price使用的是int、long基本类型,这类类型的默认值为0而非null,会导致JPQL中的is null判断永远不生效,即便不传这两个参数也会默认过滤值为0的数据,需要改成包装类型:
@Data @AllArgsConstructor @NoArgsConstructor public class ProductWrapper { private String name; private String surname; // 改为包装类型支持null值 private Integer quantity; private Long price; }
同时同步修改Repository接口中对应参数的类型:
Page<Product> findAllQuery(@Param("name") String name, @Param("surname") String surname, @Param("quantity") Integer quantity, @Param("price") Long price, Pageable pageable);
2. 修正JPQL逻辑连接符
你现有JPQL用or连接所有条件,会导致只要任意一个参数匹配就返回数据,不符合多条件联合过滤的需求,需要改成and连接。另外原有代码拼接时缺少空格,会直接导致SQL语法错误,修改时需要注意补全空格。
3. 新增LIKE模糊匹配逻辑
在JPQL中用CONCAT函数拼接模糊匹配的%符即可实现模糊查询,以下示例为前后模糊匹配,你可以根据需求调整%的位置(比如前缀匹配就只在参数末尾加%):
public interface ProductRepository extends JpaRepository<Product,Integer> { /**JPQL**/ @Query("SELECT c FROM Product c WHERE" + " (:name is null or c.name LIKE CONCAT('%', :name, '%'))" + " AND (:surname is null or c.surname LIKE CONCAT('%', :surname, '%'))" + " AND (:quantity is null or c.quantity = :quantity)" + " AND (:price is null or c.price = :price)") Page<Product> findAllQuery(@Param("name") String name, @Param("surname") String surname, @Param("quantity") Integer quantity, @Param("price") Long price, Pageable pageable); }
如果需要忽略大小写匹配,可以加上LOWER函数处理:
(:name is null or LOWER(c.name) LIKE LOWER(CONCAT('%', :name, '%')))
修改完成后,当所有入参为null时,WHERE后的所有条件都为true,会返回全量数据,符合你的预期。
内容的提问来源于stack exchange,提问作者pepe
相关产品推荐
相关产品推荐

