带有 LIKE 的 Spring JPA @Query

Posted

技术标签:

【中文标题】带有 LIKE 的 Spring JPA @Query【英文标题】:Spring JPA @Query with LIKE 【发布时间】:2014-02-22 18:08:47 【问题描述】:

我正在尝试在 CrudRepository 中创建一个方法,该方法能够为我提供用户列表,其用户名类似于输入参数(不仅以输入参数开头,而且还包含它)。我尝试使用方法 "findUserByUsernameLike(@Param("username") String username)" 但正如 Spring 文档中所述,此方法等于 “where user.username like ?1”。这对我不好,因为我已经告诉过我正在尝试获取用户名包含的所有用户...

我为该方法编写了一个查询,但它甚至没有部署。

@Repository
public interface UserRepository extends CrudRepository<User, Long> 

@Query("select u from user u where u.username like '%username%'")
List<User> findUserByUsernameLike(@Param("username") String username);

谁能帮我解决这个问题?

【问题讨论】:

您可能希望使用containing 以从索引中受益,请参阅docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/… 【参考方案1】:

您在用户名参数前遗漏了一个冒号 (:)。因此您的代码必须从以下位置更改:

@Query("select u from user u where u.username like '%username%'")

到:

@Query("select u from user u where u.username like '%:username%'")

【讨论】:

【参考方案2】:

使用Query creation from method names,查看表 4,他们解释了一些关键字。

    使用赞:select ... like :username

     List<User> findByUsernameLike(String username);
    

    起始于:select ... like :username%

     List<User> findByUsernameStartingWith(String username);
    

    结尾:select ... like %:username

     List<User> findByUsernameEndingWith(String username);
    

    包含:select ... like %:username%

     List<User> findByUsernameContaining(String username);
    

请注意,您正在寻找的答案是数字 4。你不必使用@Query

【讨论】:

这真的很有帮助,但是如果我想使用 Containing 关键字,我也可以让它不区分大小写吗?在文档中有一些关于 StringMatcher 的说法。似乎如果我使用 ExampleMatcher 创建了一个单独的函数,它会起作用,但是我可以在方法名称中声明它而不是为了添加这种不区分大小写而编写自己的函数吗? 只是想补充一点,如果需要,您也可以忽略大小写,如下所示:List&lt;User&gt; findByUsernameContainingIgnoreCase(String username); 百分号应该倒置StartingWith: select ... like :username%EndingWith: select ... like %:username ...无论如何,很好的答案...应该是公认的。谢谢。 @Robert 我有一个大写的列数据,我使用类似 JPQL 的方法并传递小写值并能够获取值。如果没有 IgnoreCase,它也会获取不正确的案例数据。为什么会发生这种奇怪的行为? @greenhorn 请打开一个单独的 *** 问题,并在表中添加一些数据示例以及您要查询的内容。【参考方案3】:

对于您的情况,您可以直接使用 JPA 方法。就像下面这样:

包含:select ... like %:username%

List<User> findByUsernameContainingIgnoreCase(String username);

这里,IgnoreCase将帮助您在忽略大小写的情况下搜索项目。

下面是一些相关的方法:

    点赞 findByFirstnameLike

    ...其中 x.firstname 像 ?1

    StartingWith findByFirstnameStartingWith

    ... x.firstname like ?1 (参数绑定附加%)

    EndingWith findByFirstnameEndingWith

    ... x.firstname like ?1 (参数绑定在前面的 %)

    包含 findByFirstnameContaining

    ...其中 x.firstname like ?1(以 % 包裹的参数绑定)

更多信息,查看this link和this link

希望对你有帮助:)

【讨论】:

谢谢!使用 JPA 约定感觉是正确的方法。【参考方案4】:

这种方式对我有用,(使用 Spring Boot 版本 2.0.1.RELEASE):

@Query("SELECT u.username FROM User u WHERE u.username LIKE %?1%")
List<String> findUsersWithPartOfName(@Param("username") String username);

说明:?1、?2、?3 等是占位符,第一个、第二个、第三个参数等。在这种情况下,将参数用 % 包围就足够了,就好像它是标准 SQL 查询一样但没有单引号。

【讨论】:

你应该更喜欢命名参数而不是数字:@Query("SELECT u.username FROM User u WHERE u.username LIKE %:username%") @Ralph,我正在尝试使用您的方式来实现这一目标,但总是得到一个包含 0 个对象的列表,而我应该得到一个包含 2 个对象的列表,请您就此提出任何建议?以下是关于这个***.com/questions/65085720/…的问题【参考方案5】:

另一种方式:我们可以使用双管道代替CONCAT 函数::lastname || '%'

@Query("select c from Customer c where c.lastName LIKE :lastname||'%'")
List<Customer> findCustomByLastName( @Param("lastname") String lastName);

你可以放在任何地方,前缀,后缀或两者兼而有之

:lastname ||'%'  
'%' || :lastname  
'%' || :lastname || '%'  

【讨论】:

【参考方案6】:

以下易于使用(无需使用 CONCAT 或 ||):

@Query("from Service s where s.category.typeAsString like :parent%")
List<Service> findAll(@Param("parent") String parent);

记录在:http://docs.spring.io/spring-data/jpa/docs/current/reference/html

【讨论】:

不需要加“SELECT s”吗?我们可以直接从“FROM”开始吗? 是的,这对于功能来说不是强制性的,但是一些拼写检查器会显示错误。【参考方案7】:

List&lt;User&gt; findByUsernameContainingIgnoreCase(String username);

为了忽略大小写问题

【讨论】:

可以使用您的解决方案进行 SQL 注入吗? @xuezhongyu01 你认为 Spring Data JPA 允许在其派生查询中注入 SQL 吗?当然,参数会被清理。【参考方案8】:
@Query("select b.equipSealRegisterId from EquipSealRegister b where b.sealName like %?1% and b.deleteFlag = '0'" )
    List<String>findBySeal(String sealname);

我已经尝试过这段代码,它可以工作。

【讨论】:

【参考方案9】:

尝试使用以下方法(它适用于我):

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

注意:JPQL 中的表名必须以大写字母开头。

【讨论】:

WHERE UPPER(u.username) LIKE CONCAT('%',UPPER(:username),'%') 进行不区分大小写的搜索 可以使用您的解决方案进行 SQL 注入吗? (因为 CONCAT 而问) @ramden 所有@Params 都经过消毒,所以没有。 你可以这样做 :username 然后 .setParameter("username", "%foo%"); 如何设置 .setParameter("username", "%foo%"); @MatthewDaumen【参考方案10】:
@Query("select u from user u where u.username LIKE :username")
List<User> findUserByUsernameLike(@Param("username") String username);

【讨论】:

谢谢,deplouing 的问题是 jpql 区分大小写,现在它正在部署,但“LIKE”不能按我的意愿工作。它只找到完全等于输入参数的记录(不包含它)。

以上是关于带有 LIKE 的 Spring JPA @Query的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA Repository Method Query 用like?

模糊查询:Spring Data JPA 如何进行模糊查询(LIKE) ?

Spring Boot,JPA和Ignite

如何使用Spring数据jpa @Query注释直接获取学生列表

java 带有Spring Boot 1.5的JPA

使用带有 LIKE 的 mysql 本机查询的 spring boot 搜索返回空