这是一本有"词"的书;以"word1;word2;word3":
的方式@Entity
@Table(name = "books")
public class Book {
...
@Column(name ="words")
private String words;
}
我需要查找包含指定单词的Books。我:
@Repository
public interface BookRepository extends JpaRepository<Book, Long>, JpaSpecificationExecutor<Book> {}
@Service
@AllArgsConstructor
public class BookServiceImpl implements BookService {
private BookRepository bookRepository;
@Override
public List<Book> getAllBooksByWord(String word) {
return bookRepository.findAll(BookSpecification.hasWord(word));
}
}
public class BookSpecification {
public final String delimiter = ";";
public static Specification<Book> hasWord(String word) {
return (root, query, cb) ->
cb.like(
root.get("words"),
MessageFormat.format("^{0}{1}|^{0}$|.*{1}{0}{1}.*|{1}{0}$", word, delimiter)
);
}
}
问题是cb.like()
不工作与POSIX正则表达式,我可以在postgresql中使用。使用cb.like()
方法,我得到一个查询SELECT ... FROM books WHERE words LIKE '^w;|^w$|.*;w;.*|;w$'
,不理解POSIX正则表达式和WHERE子句不起作用。
是否有办法强制cb.like()
创建一个带有"~"的查询?可以理解POSIX的操作符,而不是LIKE:SELECT ... FROM books WHERE words ~ '^w;|^w$|.*;w;.*|;w$'
?
是的,这是可能的,但是你需要在PostgreSQL创建一个函数:
create or replace function regexp_match(v_text in varchar, v_regexp in varchar) returns boolean
language plpgsql strict immutable
as
$$
begin
return v_text ~ v_regexp;
end
$$;
标准:
cb.equal(
cb.function(
"regexp_match",
Boolean.class,
root.get("words"),
MessageFormat.format("^{0}{1}|^{0}$|.*{1}{0}{1}.*|{1}{0}$", word, delimiter)
),
cb.literal(true)
)
虽然,我不确定HBN是否允许绑定布尔值