我有一个由以下存储库公开的实体:
public interface InsertRepository extends PagingAndSortingRepository<InsertEntity, Long>, QueryDslPredicateExecutor<InsertEntity>, QueryDslBinderCustomizer<QInsertEntity> {
@Override
default void customize(QuerydslBindings bindings, QInsertEntity insert) {
bindings.bind(String.class).all(StringPath path, Collection<? extends String> values) -> {
BooleanBuilder predicate = new BooleanBuilder();
values.forEach(value -> predicate.or(path.containsIgnoreCase(value)));
return predicate;
});
}
}
我希望它做的是将所有GET查询参数链接为逻辑OR,以便像?description=searchText&customerName=searchText
这样的查询执行如下的SQL查询:
WHERE description LIKE '%searchText%' OR customerName LIKE '%searchText%'
但是,我必须做错事,因为它不起作用 - 它将所有查询参数放入AND
查询。这导致只选择那些在customerName AND 中包含searchText
的记录。
答案 0 :(得分:1)
@kafkas提供的答案根本不准确。它的问题很少:
@Query
是obsolette - Spring会自动为您执行此操作,您只需要正确键入方法的名称。@Param
是obsolette - Spring按给定顺序自动获取参数,与方法名称中的参数匹配。findBy
而不是findOne
- 如果找到多条记录,则会导致错误。LIKE
比较,而是等于。如果您希望启动SQL查询,请使用findByXXXContaining
,如:... WHERE firstname LIKE "%name%"
CrudRepository
,它涵盖了大多数用例。总之,您的方法应该简化并看起来像这样:
public interface UserRepository extends CrudRepository<User, Long> {
User findOneByLastnameContainingOrFirstnameContaining(String lastname, String firstname);
}
这应该导致查询:
SELECT * FROM User u WHERE u.lastname LIKE '%lastname' OR u.firstname LIKE '%firstname%;'
答案 1 :(得分:0)
您可以使用命名参数,例如
示例53.使用命名参数
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
}