简体   繁体   中英

Spring Data JPA - case insensitive query w/ pattern matching

Suppose I'm implementing search functionality for a simple CMS package (just an example), and want to match posts by both their title and content . Presumably, I would have some sort of Post entity with the following underlying table structure:

+------------------------------------+
|               POST                 |
+---------+--------------+-----------+
| post_id | INTEGER      | NOT NULL, |
| title   | VARCHAR(255) | NOT NULL, |
| content | CLOB         | NOT NULL  |
+---------+--------------+-----------+

Next, I would extend Spring's JpaRepository and add the search method via @Query annotation, like so (again, just an example):

public interface PostRepository extends JpaRepository<Post, Integer> {

    @Query("SELECT p FROM Post AS p WHERE lower(p.title) LIKE lower(%:searchTerm%)"  
            + " OR lower(p.content) LIKE lower(%:searchTerm%) ORDER BY p.title")
    List<Post> findBySearchTerm(@Param("searchTerm") String searchTerm);
}

The problem is that Spring (or maybe it's just the underlying JPA provider, not sure) has a hard time parsing this query due to the lower(%:searchTerm%) expression in the WHERE clause. I've also tried other variations of this syntax, eg %lower(:searchTerm)% , but none seem to work so far. Does anybody have a good (and preferably clean) solution for this?

PS : I would prefer to use the @Query annotation for consistency's sake. However, I guess other solutions (such as Spring's method name -> query derivation or the Criteria API ) are also welcome.

1) Inject searchTerm already in lower case to the method, and use JPQL ..... lower(COLUMN_NAME) like %:searchTerm%

2) Use method names with following naming syntax, so you don't need to provide % to the JPQL ..... lower(COLUMN_NAME) :searchTerm

findBySearchTermContainingIgnoreCase(String searchTerm)
findBySearchTermStartingWithIgnoreCase(String searchTerm)

Try something like this:

@Query("SELECT u.username FROM User u WHERE u.username LIKE     
lower(CONCAT('%',:username,'%')"))
List<String> findUsersWithPartOfName(@Param("username") String username);

Notice: The table name in JPQL must start with a capital letter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM