PostgreSQL中LIKE能否与IN结合?JPA传参排除记录咨询
PostgreSQL中实现类似LIKE IN的排除逻辑及Spring Data JPA集成方案
一、PostgreSQL原生查询的正确写法
PostgreSQL没有直接的LIKE IN语法,但可以通过NOT LIKE ALL(ARRAY[...])实现类似逻辑,你之前的写法无效是因为数组构造和参数传递的问题:
- 你代码里的
ARRAY[cast(:listOrArrayOfExcludedNames AS text)]是把整个列表转成了单个文本元素,而非包含多个通配符字符串的数组。正确写法是让数组每个元素都带%匹配符:SELECT * FROM your_table WHERE varchar_field NOT LIKE ALL(ARRAY['%John%', '%Bob%', '%Sean%']) - 如果是参数化查询,需直接传入字符串数组(而非把列表转成单个文本),比如:
这里的SELECT * FROM your_table WHERE varchar_field NOT LIKE ALL(:excludedNamesArray):excludedNamesArray要对应包含'%John%'、'%Bob%'等元素的数组参数。
你用正则!~ 'John|Bob|Sean'可行,但这种方式适合固定匹配串;如果是动态生成的排除列表,数组方式更灵活易维护。
二、Spring Data JPA中传入数组/列表实现排除
1. 原生查询方式
用@Query注解编写原生SQL,直接绑定数组或列表参数:
@Repository public interface YourRepository extends JpaRepository<YourEntity, Long> { @Query(value = "SELECT * FROM your_table WHERE varchar_field NOT LIKE ALL(ARRAY[:excludedNames])", nativeQuery = true) List<YourEntity> findByExcludedNames(@Param("excludedNames") List<String> excludedNames); }
调用时需给excludedNames列表的每个元素加上%通配符:
List<String> excluded = Arrays.asList("%John%", "%Bob%", "%Sean%"); List<YourEntity> result = yourRepository.findByExcludedNames(excluded);
2. JPA Criteria API方式(无原生SQL)
如果不想用原生SQL,可通过Criteria API动态构建查询条件:
@Repository public class YourRepositoryCustomImpl implements YourRepositoryCustom { @PersistenceContext private EntityManager entityManager; @Override public List<YourEntity> findByExcludedNames(List<String> excludedNames) { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<YourEntity> query = cb.createQuery(YourEntity.class); Root<YourEntity> root = query.from(YourEntity.class); Predicate predicate = cb.conjunction(); for (String name : excludedNames) { predicate = cb.and(predicate, cb.notLike(root.get("varcharField"), name)); } query.where(predicate); return entityManager.createQuery(query).getResultList(); } }
同样,调用时需给每个元素加上%通配符。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

