2009-08-27 29 views
75

Tôi cố gắng để viết một truy vấn JPQL với một điều khoản như:Parameter tại khoản như JPQL

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 cần :value không được bọc bởi % 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

Trả lời

157

Nếu bạn làm

LIKE :code 

và sau đó làm

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

Sau đó, giá trị vẫn miễn phí từ '%' 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 thông số khác với 'mã'.

+9

Đối với hồ sơ, điều này không để bạn mở cho các cuộc tấn công tiêm JPQL vì this.value được tự động thoát đúng cách cho bạn. –

+1

Điều này '"% "+ this.value +"% "' là những gì được thoát. – Gustavo

+0

Làm cách nào để làm cho trường hợp này không nhạy cảm? –

50

Tôi không sử dụng thông số được đặt tên cho tất cả truy vấn. Ví dụ, không bình thường khi sử dụng các tham số có tên trong JpaRepository.

Để workaround tôi sử dụng JPQL CONCAT chức năng (mã này bắt chước bắt đầu với):

@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 thấy kỹ thuật này trong tài liệu xuất sắc: http://openjpa.apache.org/builds/1.0.1/apache-openjpa-1.0.1/docs/manual/jpa_overview_query.html

4

Bạn có thể sử dụng JPA LOCATE function.

VỊ (searchString, candidateString [, startIndex]): Trả về chỉ số đầu tiên của searchString trong candidateString. 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ề số my top google hit có các tham số được đảo ngược.

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

cho tôi giải pháp tốt nhất - không có nối, không có SQL injection. – hgoebl

2

Chỉ cần bỏ qua ''

LIKE %:code% 
0

Tôi không biết nếu tôi muộn hoặc ra khỏi phạm vi nhưng theo ý kiến ​​của tôi, tôi có thể làm điều đó thích:

String orgName = "anyParamValue"; 

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

q.setParameter("orgName", orgName);