【问题标题】:Spring JPA @Query with LIKE带有 LIKE 的 Spring JPA @Query
【发布时间】:2021-10-16 04:36:07
【问题描述】:

我正在尝试在 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);
}

谁能帮我解决这个问题?

【问题讨论】:

标签: java jquery sql spring jpa


【解决方案1】:
@Query("select u from user u where u.username LIKE :username")
List<User> findUserByUsernameLike(@Param("username") String username);

【讨论】:

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

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

@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
【解决方案3】:

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

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

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

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

【讨论】:

    【解决方案4】:

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

    1. 使用赞:select ... like :username

       List<User> findByUsernameLike(String username);
      
    2. 起始于:select ... like :username%

       List<User> findByUsernameStartingWith(String username);
      
    3. 结尾:select ... like %:username

       List<User> findByUsernameEndingWith(String username);
      
    4. 包含: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 请打开一个单独的 StackOverflow 问题,并在表中添加一些数据示例以及您要查询的内容。
    【解决方案5】:
    @Query("select b.equipSealRegisterId from EquipSealRegister b where b.sealName like %?1% and b.deleteFlag = '0'" )
        List<String>findBySeal(String sealname);
    

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

    【讨论】:

      【解决方案6】:

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

      为了忽略大小写问题

      【讨论】:

      • 可以使用您的解决方案进行 SQL 注入吗?
      • @xuezhongyu01 你认为 Spring Data JPA 允许在其派生查询中注入 SQL 吗?当然,参数会被清理。
      【解决方案7】:

      以下易于使用(无需使用 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”开始吗?
      • 是的,这对于功能来说不是强制性的,但是一些拼写检查器会显示错误。
      【解决方案8】:

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

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

      List<User> findByUsernameContainingIgnoreCase(String username);
      

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

      下面是一些相关的方法:

      1. 点赞 findByFirstnameLike

        ...其中 x.firstname 像 ?1

      2. StartingWith findByFirstnameStartingWith

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

      3. EndingWith findByFirstnameEndingWith

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

      4. 包含 findByFirstnameContaining

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

      更多信息,查看this linkthis link

      希望对你有帮助:)

      【讨论】:

      • 谢谢!使用 JPA 约定感觉是正确的方法。
      【解决方案9】:

      这种方式对我有用,(使用 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 个对象的列表,请您就此提出任何建议?以下是关于这个stackoverflow.com/questions/65085720/…的问题
      【解决方案10】:

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

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

      到:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-31
        • 2020-05-20
        • 2020-11-26
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        相关资源
        最近更新 更多