Parameter seperti klausa JPQL

90

Saya mencoba menulis kueri JPQL dengan klausa like:

LIKE '%:code%'

Saya ingin memiliki kode = 4 dan menemukan

455
554
646
...

Saya tidak bisa lewat :code = '%value%'

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

karena di tempat lain saya :valuetidak perlu dibungkus oleh %karakter. Ada bantuan?

Manuel Drieschmanns
sumber
2
@ Manuele Piastra: Bukankah jawaban di bawah yang Anda cari?
wmorrison365

Jawaban:

169

Jika kamu melakukan

LIKE :code

dan kemudian lakukan

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

Kemudian nilai tetap bebas dari tanda '%'. Jika Anda perlu menggunakannya di tempat lain dalam kueri yang sama, cukup gunakan nama parameter lain selain 'kode'.

kepala kapal
sumber
9
Sebagai catatan, ini tidak membuat Anda terbuka terhadap serangan injeksi JPQL karena this.value secara otomatis lolos dengan benar untuk Anda.
László van den Hoek
3
Inilah "%" + this.value + "%"yang lolos.
Gustavo
2
Bagaimana cara membuat ini peka huruf besar-kecil?
EM-Creations
55

Saya tidak menggunakan parameter bernama untuk semua kueri. Misalnya, tidak biasa menggunakan parameter bernama di JpaRepository .

Untuk mengatasinya, saya menggunakan fungsi JPQL CONCAT (kode ini dimulai dengan ):

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

Saya menemukan teknik ini dalam dokumen yang sangat bagus: http://openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html

gavenkoa.dll
sumber
2
Catatan: CONCAT (? 2, '%') akan menambahkan '%' ke akhir parameter, gunakan CONCAT ('%',? 2, '%') untuk menambahkannya ke awal dan akhir parameter.
Muizz Mahdy
7

Anda dapat menggunakan fungsi JPA LOCATE .

LOCATE (searchString, kandidatString [, startIndex]) : Mengembalikan indeks pertama searchString di kandidatString. Posisi berbasis 1. Jika string tidak ditemukan, mengembalikan 0.

FYI: Dokumentasi di hit google teratas saya memiliki parameter terbalik.

SELECT 
  e
FROM 
  entity e
WHERE
  (0 < LOCATE(:searchStr, e.property))
David Carlson
sumber
1
bagi saya solusi terbaik - tanpa penggabungan, tanpa injeksi SQL.
hgoebl
4

Saya tidak tahu apakah saya terlambat atau di luar jangkauan tetapi menurut saya saya bisa melakukannya seperti:

String orgName = "anyParamValue";

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

q.setParameter("orgName", orgName);
Ishimwe Aubain Consolateur
sumber
2

Ada metode like () yang bagus di API kriteria JPA. Coba gunakan itu, semoga bisa membantu.

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%"));
Haroon
sumber
1
  1. Gunakan di bawah kueri JPQL.
select i from Instructor i where i.address LIKE CONCAT('%',:address ,'%')");
  1. Gunakan di bawah Kode kriteria untuk hal yang sama:
@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%")));
}
Vaneet Kataria
sumber
0

Tinggalkan saja ''

LIKE %:code%
Sehtim
sumber
Suara negatif: tidak berfungsi, ini mengubah nama parameter menjadi kode%
kaiser
0

Gunakan JpaRepositoryatau CrudRepositorysebagai antarmuka repositori:

@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());
    }
}
KarishmaP
sumber