Tham số trong mệnh đề tương tự JPQL


90

Tôi đang cố gắng viết một truy vấn JPQL với mệnh đề tương tự:

LIKE '%:code%'

Tôi muốn có mã = ​​4 và tìm

455
554
646
...

Tôi không thể vượt qua :code = '%value%'

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

bởi vì ở một nơi khác, tôi :valuekhông cần phải được bao bọc bởi các %ký tự. Bất kỳ giúp đỡ?


2
@Manuele Piastra: Câu trả lời dưới đây không phải là những gì bạn đang tìm kiếm?
wmorrison365

Câu trả lời:


169

Nếu bạn làm

LIKE :code

và sau đó làm

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

Sau đó, giá trị vẫn không có dấu '%'. Nếu bạn cần sử dụng nó ở một nơi khác trong cùng một truy vấn, chỉ cần sử dụng một tên tham số khác ngoài 'mã'.


9
Đối với bản ghi, điều này sẽ không khiến bạn bị tấn công JPQL bởi vì giá trị this.value tự động được thoát đúng cách cho bạn.
László van den Hoek

3
Đây "%" + this.value + "%"là những gì được thoát ra.
Gustavo

2
Làm cách nào để phân biệt chữ hoa chữ thường này?
EM-Creations

55

Tôi không sử dụng các tham số được đặt tên cho tất cả các truy vấn. Ví dụ, việc sử dụng các tham số được đặt tên trong JpaRepository là điều bất thường .

Để giải quyết vấn đề này, tôi sử dụng hàm JPQL CONCAT (mã này mô phỏng bắt đầu bằng ):

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

Tôi đã tìm thấy kỹ thuật này trong tài liệu tuyệt vời: http://openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html


2
Lưu ý: CONCAT (? 2, '%') sẽ thêm '%' vào cuối tham số, hãy sử dụng CONCAT ('%',? 2, '%') để thêm nó vào đầu và cuối tham số.
Muizz Mahdy

7

Bạn có thể sử dụng hàm JPA LOCATE .

LOCATE (searchString, applicationString [, startIndex]) : Trả về chỉ mục đầu tiên của searchString trong ứng viênString. Vị trí dựa trên 1. Nếu không tìm thấy chuỗi, trả về 0.

FYI: Tài liệu về lượt truy cập google hàng đầu của tôi đã đảo ngược các thông số.

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

1
đối với tôi giải pháp tốt nhất - không nối, không chèn SQL.
hgoebl

4

Tôi không biết liệu mình có đến muộn hay không nhưng theo ý kiến ​​của tôi, tôi có thể làm như sau:

String orgName = "anyParamValue";

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

q.setParameter("orgName", orgName);

2

Có một phương thức like () rất hay trong API tiêu chí JPA. Hãy cố gắng sử dụng nó, hy vọng nó sẽ giúp ích.

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. Sử dụng truy vấn JPQL bên dưới.
select i from Instructor i where i.address LIKE CONCAT('%',:address ,'%')");
  1. Sử dụng mã Tiêu chí bên dưới cho giống nhau:
@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

Chỉ cần bỏ đi ''

LIKE %:code%

Downvote: không làm việc, điều này thay đổi tên tham số để mã%
kaiser

0

Sử dụng JpaRepositoryhoặc CrudRepositorylàm giao diện kho lưu trữ:

@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());
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.