Spring JPA @Query与LIKE


92

我正在尝试在CrudRepository中创建一个方法,该方法将向我提供用户列表,其用户名类似于输入参数(不仅以它开头,还包含它)。我尝试使用method,"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);
}

有人可以帮我吗?


4
你可能想使用containing,以便从指标的好处,看到docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/...

Answers:


168

尝试使用以下方法(对我有用):

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

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


10
或者WHERE UPPER(u.username) LIKE CONCAT('%',UPPER(:username),'%')做一个区分大小写的搜索
布拉德·梅斯

使用SQL-Injection解决方案可能吗?(由于CONCAT提出问题)
猛击

@ramden所有@Params都经过消毒,所以没有。
nurettin

您可以先执行:username然后执行.setParameter(“ username”,“%foo%”);
马修·道门

如何设置.setParameter(“ username”,“%foo%”); @MatthewDaumen
xuezhongyu01

115

使用从方法名称创建查询,请检查表4,其中解释了一些关键字。

  1. 使用赞:选择...赞:用户名

    List<User> findByUsernameLike(String username);
  2. StartingWith:选择...,例如:username%

    List<User> findByUsernameStartingWith(String username);
  3. EndingWith:选择...,例如%:username

    List<User> findByUsernameEndingWith(String username);
  4. 包含:选择...,例如%:username%

    List<User> findByUsernameContaining(String username);

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


这确实很有帮助,但是如果我想使用Containing关键字,是否还可以使其不区分大小写?在文档中有一些关于StringMatcher的说法。看来,如果我使用ExampleMatcher创建了一个单独的函数,它将起作用,但是我可以以某种方式在方法名称中声明它,而不是仅仅为了增加这种不区分大小写而编写自己的函数吗?
V. Samma

11
只是想补充一下,如果需要,您还可以忽略大小写,例如: List<User> findByUsernameContainingIgnoreCase(String username);
罗伯特·罗伯特(Robert Robert)

百分号应颠倒,StartingWith: select ... like :username%并且EndingWith: select ... like %:username……总之应该是一个很好的答案。谢谢。
亚历山德罗(Alessandro)

@Robert我有一个大写的列数据,我使用了像JPQL这样的方法,并传递了小写的值并能够获取这些值。如果没有IgnoreCase,它也会获取不正确的案例数据。为什么会发生这种奇怪的行为?
greenhorn

@greenhorn请打开一个单独的StackOverflow问题,并在表中添加一些数据示例以及您要查询的内容。
罗伯特

25

另一种方式:相反,CONCAT我们可以使用双管道::lastname || '%'

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

您可以在任何地方放置前缀,后缀或两者都放置

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

10

List<User> findByUsernameContainingIgnoreCase(String username);

为了忽略案例问题


使用SQL-Injection解决方案可能吗?
xuezhongyu01


8

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

包含:选择...,例如%:username%

List<User> findByUsernameContainingIgnoreCase(String username);

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

以下是一些相关方法:

  1. 喜欢 findByFirstnameLike

    …其中x.firstname像?1

  2. 从...开始 findByFirstnameStartingWith

    …其中x.firstname如?1(参数与附加的%绑定)

  3. 结尾于 findByFirstnameEndingWith

    …其中x.firstname如?1(参数与前缀%绑定)

  4. 内含 findByFirstnameContaining

    …其中x.firstname如?1(参数绑定在%中)

更多信息,请查看此链接此链接

希望这个能对您有所帮助 :)


谢谢!使用JPA约定感觉很正确。
FigletNewton

3

这种方式对我有用(使用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
@Query("select u from user u where u.username LIKE :username")
List<User> findUserByUsernameLike(@Param("username") String username);

谢谢,令人沮丧的问题是jpql区分大小写,现在正在部署,但是“ LIKE”无法按我的意愿工作。它只查找完全等于输入参数(不包含输入参数)的记录。
维克托里亚2014年

-1
@Query("select b.equipSealRegisterId from EquipSealRegister b where b.sealName like %?1% and b.deleteFlag = '0'" )
    List<String>findBySeal(String sealname);

我已经尝试过此代码,并且可以正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.