พารามิเตอร์ใน like clause JPQL


92

ฉันพยายามเขียนแบบสอบถาม JPQL ด้วยประโยค like:

LIKE '%:code%'

ฉันต้องการรหัส = 4 และค้นหา

455
554
646
...

ฉันไม่สามารถผ่านไปได้ :code = '%value%'

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

เพราะในที่อื่นฉัน:valueไม่จำเป็นต้องพัน%อักขระ ความช่วยเหลือใด ๆ


2
@ Manuele Piastra: คำตอบด้านล่างไม่ใช่สิ่งที่คุณกำลังมองหาใช่หรือไม่?
wmorrison365

คำตอบ:


170

ถ้าคุณทำ

LIKE :code

แล้วทำ

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

จากนั้นค่าจะยังคงเป็นอิสระจากเครื่องหมาย "%" หากคุณต้องการใช้ที่อื่นในแบบสอบถามเดียวกันให้ใช้ชื่อพารามิเตอร์อื่นที่ไม่ใช่ 'รหัส'


9
สำหรับบันทึกนี้ไม่ได้ทำให้คุณเปิดรับการโจมตีด้วยการฉีด JPQL เพราะ this.value จะถูกหลีกเลี่ยงโดยอัตโนมัติสำหรับคุณ
László van den Hoek

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 (searchString, ApplicantString [, startIndex]) : ส่งกลับดัชนีแรกของ searchString ใน ApplicString ตำแหน่งจะขึ้นอยู่กับ 1 หากไม่พบสตริงให้ส่งกลับ 0

FYI: เอกสารเกี่ยวกับGoogle Hit อันดับต้น ๆ ของฉันมีการย้อนกลับของพารามิเตอร์

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

1
ทางออกที่ดีที่สุดสำหรับฉัน - ไม่มีการต่อกันไม่มีการฉีด SQL
hgoebl

4

ฉันไม่รู้ว่าฉันมาสายหรืออยู่นอกขอบเขต แต่ในความคิดของฉันฉันสามารถทำได้เช่น:

String orgName = "anyParamValue";

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

q.setParameter("orgName", orgName);

3

มีวิธีการ like () ที่ดีใน JPA criteria API ลองใช้ดูหวังว่ามันจะช่วยได้

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%

Downvote: ไม่ทำงานจะเปลี่ยนชื่อพารามิเตอร์เป็นรหัส%
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.