2016-05-12 22 views
6

Tôi đang cố gắng để viết một truy vấn tương tự nhưTiêu chuẩn API giới hạn kết quả trong subquery

select * from Table a 
where a.parent_id in 
    (select b.id from Table b 
    where b.state_cd = ? 
    and rownum < 100) 

sử dụng Criteria API. Tôi có thể đạt được các truy vấn mà không có sự giới hạn rownum trên tốt subquery sử dụng mã tương tự như https://stackoverflow.com/a/4668015/597419 nhưng tôi dường như không thể tìm ra cách để appose một giới hạn về Subquery

+0

Nếu bạn không thể tìm ra cách để giới hạn truy vấn con, thì cách sử dụng kết nối? – Traubenfuchs

+1

@Traubenfuchs Phải có hơn 100 kết quả trong truy vấn. Hãy nghĩ về truy vấn phụ là bản ghi cha mẹ và kết quả tôi muốn quay lại với tư cách là con cái. Một số cha mẹ có nhiều con. Tôi không thấy làm thế nào tôi có thể hoàn thành việc tìm kiếm trẻ em cho 100 bậc cha mẹ đầu tiên bằng cách tham gia. – Danny

+0

Mệnh đề where là động và thường là nhiều hơn thì chỉ là các hàng X đầu tiên trong bảng. Tôi nên nói rằng trong câu hỏi. – Danny

Trả lời

7

Trong Hibernate, bạn có thể thêm những hạn chế SQL thực tế, nhưng đáng chú ý là điều này sẽ mang tính đặc thù của Oracle. Nếu bạn chuyển sang PostgreSQL, điều này sẽ bị ngắt và bạn cần LIMIT 100 thay thế.

DetachedCriteria criteria = DetachedCriteria.forClass(Domain.class) 
    .add(Restrictions.sqlRestriction("rownum < 100")); 

Trong JPA API, câu trả lời ngắn là bạn có thể không ... Trong câu hỏi của bạn, bạn đề xuất sử dụng API Tiêu chuẩn (cùng với một subquery). Tuy nhiên, nó không phải là cho đến khi bạn thực sự gọi EntityManager.createQuery(criteriaQuery) mà bạn sẽ nhận được một TypedQuery nơi bạn có thể chỉ định giá trị maxResult.

Điều đó nói rằng, bạn có thể phá vỡ nó thành 2 truy vấn, là người đầu tiên mà bạn có được kết quả nội chọn (tối đa 100) và sau đó một lần 2 Criteria nơi bạn lấy danh sách kết quả là một in():

// inner query 
CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<YourClass> innerCriteriaQuery = cb.createQuery(YourClass.class); 
Root<YourClass> yourClass = innerCriteriaQuery.from(YourClass.class); 

innerCriteriaQuery.select(yourClass).where(
    cb.equal(yourClass.get(YourClass_.stateCode), someStateValue)); 

// list of 100 parent ids 
List<YourClass> list = em.createQuery(innerCriteriaQuery).setMaxResults(100).getResultList(); 

// outer query 
CriteriaQuery<YourClass> criteriaQuery = cb.createQuery(YourClass.class); 
Root<YourClass> yourClass = criteriaQuery.from(YourClass.class); 

criteriaQuery.select(yourClass).where(
    cb.in(yourClass.get(YourClass_.parentId)).value(list); 

return em.createQuery(criteriaQuery).getResultList(); 
+0

Điều này đang sử dụng API của Hibernate, không phải [API tiêu chí] (http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html) – Danny

+0

Giám sát một phần của tôi ... đã thêm thông tin cụ thể về API như tốt. Đáng buồn thay, không có cách nào để làm điều đó với một 'Tiêu chí' duy nhất. –

+0

Điều này rất hữu ích, nhưng vẫn không phải là câu trả lời lý tưởng cho tôi. Có những lúc mà danh sách này sẽ lên tới 1000 mục, không may Oracle có giới hạn chỉ 1000 mục trong mệnh đề 'in'. Tôi vẫn không nhìn thấy bất cứ điều gì trong API cho phép tôi sử dụng 'rownum' trong truy vấn phụ, vì vậy tôi có thể sẽ phải đi tuyến đường này và thực hiện nhiều truy vấn giới hạn mỗi truy vấn đến 1000 mục. – Danny

Các vấn đề liên quan