LIKEを使用したSpring JPA @Query


93

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);
}

誰かがこれを手伝ってくれる?


4
containingインデックスのメリットを活用するには、docs.spring.io / spring

回答:


170

次のアプローチを試してみてください(私にとってはうまくいきます):

@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),'%')大文字と小文字を区別しない検索を実行するには
Brad Mace

あなたのソリューションを使用したSQLインジェクションは可能ですか?(CONCATのために尋ねる)
ramden

@ramdenすべて@Paramのsはサニタイズされるので、いいえ。
ヌレティン2018年

:usernameを実行し、次に.setParameter( "username"、 "%foo%");のように実行できます。
マシュー・ドーメン

.setParameter( "username"、 "%foo%");の設定方法 @MatthewDaumen
xuezhongyu01

120

メソッド名からのクエリ作成を使用して、いくつかのキーワードについて説明している表4を確認してください。

  1. Likeの使用:select ... like:username

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

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

    List<User> findByUsernameEndingWith(String username);
  4. 含む:select ... like%:username%

    List<User> findByUsernameContaining(String username);

あなたが探している答えは4番であることに注意してください。@Queryを使用する必要はありません


これは本当に役に立ちますが、Containingキーワードを使用したい場合は、大文字と小文字を区別しないようにすることもできますか?ドキュメントでは、StringMatcherについて何かが述べられています。ExampleMatcherで別の関数を作成した場合は機能すると思われますが、この大文字と小文字を区別しないために独自の関数を記述しないように、メソッド名でなんとか宣言できますか?
V.サマ2017

11
:ちょうどこのように、必要に応じて、あなたも、ケースを無視することができることを追加したい List<User> findByUsernameContainingIgnoreCase(String username);
ロバート

パーセント記号は反転StartingWith: select ... like :username%している必要がありEndingWith: select ... like %:usernameます...とにかく素晴らしい答えは... ありがとう。
アレッサンドロ

@Robert大文字の列データがあり、JPQLのようなメソッドを使用し、小文字の値を渡して値を取得できました。IgnoreCaseがないと、不適切なケースのデータを取得します。なぜこの奇妙な行動が起こったのですか?
グリーンホーン2018年

@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インジェクションは可能ですか?
xuezhongyu01 '09 / 09/30


8

あなたのケースでは、直接JPAメソッドを使用できます。それは怒鳴るようなものです:

含む:select ... like%:username%

List<User> findByUsernameContainingIgnoreCase(String username);

ここでは、IgnoreCaseは大文字小文字を無視してアイテムを検索するのに役立ちます。

関連するメソッドは次のとおりです。

  1. お気に入り findByFirstnameLike

    …ここで?1のようなx.firstname

  2. で始まります findByFirstnameStartingWith

    …ここで?1のようなx.firstname(%が付加されたパラメーターバインド)

  3. EndingWith findByFirstnameEndingWith

    …ここで?1のようなx.firstname(先頭に%を付けてバインドされたパラメーター)

  4. 含む findByFirstnameContaining

    …?1のようなx.firstname(%でラップされたパラメーターバインド)

詳細、このリンクこのリンクを表示

これがあなたに役立つことを願っています:)


ありがとう!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などは、1番目、2番目、3番目のパラメーターなどのプレースホルダーです。この場合、標準のSQLクエリであるかのように、パラメーターを%で囲むだけで十分ですが、単一引用符。


:あなたは、数字の代わりに名前付きパラメータをprefere必要があります@Query("SELECT u.username FROM User u WHERE u.username LIKE %:username%")
ラルフ・

0
@Query("select u from user u where u.username LIKE :username")
List<User> findUserByUsernameLike(@Param("username") String username);

おかげで、deplouingの問題は、jpqlが大文字と小文字を区別することでしたが、現在はデプロイされていますが、「LIKE」は希望どおりに機能しません。入力パラメーターと完全に等しい(それを含まない)レコードのみを検索します。
Viktoriia 2014年

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

私はこのコードを試してみましたが、うまくいきます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.