LIKE句JPQLのパラメータ


90

like句を使用してJPQLクエリを記述しようとしています。

LIKE '%:code%'

code = 4を見つけて見つけたい

455
554
646
...

通れません :code = '%value%'

namedQuery.setParameter("%" + this.value + "%");

別の場所で:value%イワナに包まれる必要はないからです。何か助けは?


2
@Manuele Piastra:以下の答えはあなたが探していたものではありませんか?
wmorrison365 2013年

回答:


169

もし、するなら

LIKE :code

そして次に

namedQuery.setParameter("code", "%" + this.value + "%");

その後、値には「%」記号がなくなります。同じクエリの別の場所で使用する必要がある場合は、 'code'以外の別のパラメーター名を使用してください。


9
参考までに、this.valueは自動的に適切にエスケープされるため、JPQLインジェクション攻撃にさらされることはありません。
ラースローファンデンホーク

3
これ"%" + this.value + "%"はエスケープされたものです。
Gustavo

2
大文字と小文字を区別しないようにするにはどうすればよいですか?
EM-Creations

55

名前付きパラメーターをすべてのクエリに使用するわけではありません。たとえば、JpaRepositoryで名前付きパラメーターを使用するのは珍しいことです。

回避策として、JPQL CONCAT関数を使用します(このコードはで開始をエミュレートします)。

@Repository
public interface BranchRepository extends JpaRepository<Branch, String> {
    private static final String QUERY = "select b from Branch b"
       + " left join b.filial f"
       + " where f.id = ?1 and b.id like CONCAT(?2, '%')";
    @Query(QUERY)
    List<Branch> findByFilialAndBranchLike(String filialId, String branchCode);
}

私はこのテクニックを優れたドキュメントで見つけました:http : //openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html


2
注:CONCAT(?2、 '%')はパラメーターの最後に '%'を追加します。CONCAT( '%'、?2、 '%')を使用してパラメーターの最初と最後に追加します。
Muizz Mahdy

7

JPA LOCATE関数を使用できます。

LOCATE(searchString、候補文字列[、開始インデックス]):候補文字列の検索文字列の最初のインデックスを返します。位置は1ベースです。文字列が見つからない場合、0を返します。

参考:Googleの上位ヒットに関するドキュメントでは、パラメータが逆になっています。

SELECT 
  e
FROM 
  entity e
WHERE
  (0 < LOCATE(:searchStr, e.property))

1
私にとって最良の解決策-連結なし、SQLインジェクションなし。
hgoebl 2017

4

私が遅れているのか、範囲外であるのかはわかりませんが、私の考えでは次のようにすることができます。

String orgName = "anyParamValue";

Query q = em.createQuery("Select O from Organization O where O.orgName LIKE '%:orgName%'");

q.setParameter("orgName", orgName);

2

JPA基準APIには、素晴らしいlike()メソッドがあります。それを使用してみてください、それが役立つことを願っています。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery criteriaQuery = cb.createQuery(Employees.class);
Root<Employees> rootOfQuery = criteriaQuery.from(Employees.class);
criteriaQuery.select(rootOfQuery).where(cb.like(rootOfQuery.get("firstName"), "H%"));

1
  1. 以下のJPQLクエリを使用します。
select i from Instructor i where i.address LIKE CONCAT('%',:address ,'%')");
  1. 同じために以下の基準コードを使用します。
@Test
public void findAllHavingAddressLike() {
    CriteriaBuilder cb = criteriaUtils.criteriaBuilder();
    CriteriaQuery<Instructor> cq = cb.createQuery(Instructor.class);
    Root<Instructor> root = cq.from(Instructor.class);
    printResultList(cq.select(root).where(
        cb.like(root.get(Instructor_.address), "%#1074%")));
}

0

そのままにしてください ''

LIKE %:code%

反対票:機能しません。パラメーター名がcode%に変更されます
kaiser

0

JpaRepositoryまたはCrudRepositoryリポジトリインターフェイスとして使用:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

    @Query("SELECT t from Customer t where LOWER(t.name) LIKE %:name%")
    public List<Customer> findByName(@Param("name") String name);

}


@Service(value="customerService")
public class CustomerServiceImpl implements CustomerService {

    private CustomerRepository customerRepository;
    
    //...

    @Override
    public List<Customer> pattern(String text) throws Exception {
        return customerRepository.findByName(text.toLowerCase());
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.