通过 Criteria 创建存储库。 我需要能够使用 LIKE 和 IGNORE_CASE 字符串搜索值列表,就像在 POSTGRE
ILIKE
方法中一样。
我的限制是我需要分页输出信息。
我知道 Spring Data JPA 有这样的功能,但另一个限制是 Spring Data JDBC。
当我开始设置 Criteria 时,我发现 .ignoreCase(true) 无法正常工作,例如: 数据库中的值列表:
qwe
qwer
qwert
qwerty
Qwerty
QwertY
QWERTY
请求
qwer
只回复一个QWERTY
spring-data-relational-3.1.0.jar
@Repository
@RequiredArgsConstructor
public class Repository {
private final JdbcAggregateTemplate jdbc;
public Page<Account> getList(@NonNull AccountRequest filter, @NonNull Pageable pageable) {
Criteria criteria = Criteria.empty();
if (StringUtils.isNotBlank(filter.getAccountCode())) {
criteria = criteria.and(ACCOUNT_CODE).like("%" + (filter.getAccountCode() + "%")).ignoreCase(true);
}
Query query = Query.query(criteria).with(pageable);
List<Account> all = IteratorUtils.toList(jdbc.findAll(query, Account.class).iterator());
long count = jdbc.count(Query.query(criteria), domainType);
return new PageImpl<>(all, pageable, count);
}
预计出现 6 次,但只出现 1 次
有没有办法手动忽略分页输出,或者问题可能在更新中得到解决?
我尝试重现该问题,但未能演示您所描述的行为,但我确实发现了问题。
like
忽略大小写似乎工作得很好。
但是 Pageable
中的 Query
似乎被忽略了。
但是如果你使用 findAll(Query, Class, Pageable)
它工作得很好,你甚至可以得到一个完整的 Page
实例。
无需手动执行计数并构造结果。
record Demo (@Id Long id, String name){
static Demo demo(String name) {
return new Demo(null, name);
}
}
@SpringBootTest
class CaseInsensitiveLikeApplicationTests {
@Autowired
JdbcAggregateTemplate jdbc;
@BeforeEach
void setup() {
jdbc.deleteAll(Demo.class);
jdbc.saveAll(List.of(demo("ONE"), demo("drone"), demo("donE"), demo("other")));
}
@Test
void likeWithIgnoreCaseWorksAsExpected() {
assertThat(getList()).extracting(d -> d.name()).containsExactlyInAnyOrder("ONE", "drone", "donE");
}
@Test
void pageableInQuery() {
assertThat(getPage1(Pageable.ofSize(2))).hasSize(3); // this is actually not expected!
}
@Test
void separatePageable() {
assertThat(getPage2(Pageable.ofSize(2))).hasSize(2);
}
Iterable<Demo> getList() {
Criteria criteria = Criteria.where("name").like("%" + "One" + "%").ignoreCase(true);
Query query = Query.query(criteria);
return jdbc.findAll(query, Demo.class);
}
Iterable<Demo> getPage1(Pageable pageable) {
Criteria criteria = Criteria.where("name").like("%" + "ne" + "%").ignoreCase(true);
Query query = Query.query(criteria);
query.with(pageable);
return jdbc.findAll(query, Demo.class);
}
Iterable<Demo> getPage2(Pageable pageable) {
Criteria criteria = Criteria.where("name").like("%" + "ne" + "%").ignoreCase(true);
Query query = Query.query(criteria);
return jdbc.findAll(query, Demo.class, pageable);
}
}