Nếu không sử dụng
CriteriaQuery#select()
:Khi nào sử dụng mệnh đề lựa chọn trong API tiêu chuẩn JPA?public List<Address> getAddressOfManager(String designation, String name, String orderByColumn) { Boolean ascending = false; CriteriaBuilder cb = emanager.getCriteriaBuilder(); CriteriaQuery<Address> cq = cb.createQuery(Address.class); Root<Address> root = cq.from(Address.class); //cq.select(root); <------------- Join<Address, Employee> employeeAddress = root.join(Address_.employee); Join<Employee,Project> employeeProject = employeeAddress.join(Employee_.project); cq.where(cb.or(cb.equal(employeeProject.get(Project_.name), name),cb.equal(employeeAddress.get(Employee_.designation), designation))); Order order = ascending ? cb.asc(root.get(orderByColumn)) : cb.desc(root.get(orderByColumn)); cq.orderBy(order); List<Address> result = emanager.createQuery(cq).getResultList(); return result; }
Với
CriteriaQuery#select()
:public List<Address> getAddressOfManager(String designation, String name, String orderByColumn) { Boolean ascending = false; CriteriaBuilder cb = emanager.getCriteriaBuilder(); CriteriaQuery<Address> cq = cb.createQuery(Address.class); Root<Address> root = cq.from(Address.class); cq.select(root); //<---------------- Join<Address, Employee> employeeAddress = root.join(Address_.employee); Join<Employee,Project> employeeProject = employeeAddress.join(Employee_.project); cq.where(cb.or(cb.equal(employeeProject.get(Project_.name), name),cb.equal(employeeAddress.get(Employee_.designation), designation))); Order order = ascending ? cb.asc(root.get(orderByColumn)) : cb.desc(root.get(orderByColumn)); cq.orderBy(order); List<Address> result = emanager.createQuery(cq).getResultList(); return result; }
Bây giờ, tôi bối rối như khi sử dụng
select()
trong JPA tiêu chí truy vấn.
Trả lời
Về cơ bản có hai cách để xác định hạn chiếu (hoặc đơn giản là nói thuật ngữ lựa chọn) trên giao diện CriteriaQuery<T>
trong đó kết quả truy vấn là để được xác định:
CriteriaQuery<T> select(Selection<? extends T> selection);
CriteriaQuery<T> multiselect(Selection<?>... selections);
Thường thì thuật ngữ dự báo được sử dụng là lớp ứng cử viên (Address
trong các ví dụ của bạn) của chính truy vấn đó. Nó có thể được ngầm định như trong ví dụ đầu tiên của bạn.
Truy vấn từ thực thể Address
trong ví dụ đầu tiên của bạn không chỉ định rõ thuật ngữ dự báo của nó và nó giống như chọn chính xác lớp ứng cử viên trong trường hợp này.
Thực thể liên tục của ứng cử viên là thuật ngữ dự đoán duy nhất được suy diễn ngầm.
tuy nhiên khi kết quả dự kiến của truy vấn là, một cái gì đó khác hơn là thực thể dai dẳng ứng cử viên thân, một số cấu trúc khác có sẵn để hình thành kết quả của truy vấn. Các cấu trúc này có sẵn trong giao diện CriteriaBuilder
.
phương pháp để hình thành kết quả truy vấn:
CompoundSelection<Y> construct(Class<Y> result, Selection<?>... terms);
CompoundSelection<Object[]> array(Selection<?>... terms);
CompoundSelection<Tuple> tuple(Selection<?>... terms);
Vì lợi ích của sự hoàn chỉnh mà thôi, tôi sẽ cố gắng để chứng minh mỗi trong số họ lần lượt với một ví dụ đơn giản cho mỗi người trong số họ.
Shaping kết quả truy vấn vào trường hợp của một lớp (một tổ chức phi dai dẳng) bởi construct()
:
Phương pháp construct()
tạo ra một thể hiện của đối số lớp nhất định và gọi một constructor (của một tổ chức phi -nhân viên thực hiện) với các giá trị từ các điều khoản lựa chọn đầu vào. Các đối số này cho hàm tạo của một thực thể không liên tục (không phải là một thực thể, một lớp Java đơn giản) phải khớp với số, thứ tự và kiểu (kiểu dữ liệu) với các giá trị tương ứng với các điều kiện lựa chọn đầu vào, chẳng hạn.
CriteriaQuery<EmployeeDetails> q = cb.createQuery(EmployeeDetails.class);
Root<Employee> root = q.from(Employee.class);
q.select(cb.construct(EmployeeDetails.class, root.get(Employee_.empName), root.get(Employee_.salary));
EmployeeDetails
trong trường hợp này, là một lớp Java đơn giản - một tổ chức phi dai dẳng mà có một nhà xây dựng mà phải mất hai tham số kiểu String
(ví empName
) và BigDecimal
(ví salary
).
Truy vấn trả về một List<EmployeeDetails>
- một tổ chức phi dai dẳng từ chọn Employee
s - một thực thể dai dẳng.
Tùy thuộc vào số hàng được trả về, truy vấn cũng có thể trả lại EmployeeDetails
bằng cách sử dụng phương pháp getSingleResult()
.
Nhiều mục lựa chọn cũng có thể được kết hợp thành cụm từ lựa chọn kết hợp đại diện cho Object[]
hoặc Tuple
như được hiển thị bên dưới.
Shaping kết quả truy vấn vào một Object[]
:
CriteriaQuery<Object[]> q = cb.createQuery(Object[].class);
Root<Employee> root = q.from(Employee.class);
q.select(cb.array(root.get(Employee_.empName), root.get(Employee_.salary));
List<Object[]> list = entityManager.createQuery(q).getResultList();
Như có thể thấy, các truy vấn trả về một List<Object[]>
. Mỗi phần tử của danh sách này chứa một mảng dựa trên 0 là Object
s - Object[]
.
Shaping kết quả truy vấn vào một Tuple
:
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Employee> root = q.from(Employee.class);
Selection<String> empName = root.get(Employee_.empName).alias("empName");
q.select(cb.tuple(empName, root.get(Employee_.salary).alias("salary");
List<Tuple> list = entityManager.createQuery(q).getResultList();
String employeeName = list.get(0).get("empName");//Referring to by using its alias (empName)
String employeeSalary = list.get(0).get(1);//Referring to by using its index (salary)
//Iterate over a list of tuples through a foreach loop using alias.
for (Tuple tuple : list) {
System.out.println(tuple.get("empName") + " : " + tuple.get("salary"));
}
Truy vấn trả về một List<Tuple>
. Các giá trị được giữ bởi một Tuple
có thể truy cập được bằng chỉ số nguyên 0 dựa trên, sử dụng tên bí danh của TupleElement
hoặc trực tiếp bởi TupleElement
.
CriteriaBuilder#createTupleQuery()
tương tự như CriteriaBuilder#createQuery(Tuple.class)
.
Sử dụng multiselect()
để giải thích các điều khoản dựa trên loại kết quả:
Cụm từ nhập sẽ tự động được giải thích bởi multiselect()
phương pháp dựa trên loại kết quả của CriteriaQuery
để tự động đến hình dạng của kết quả - các kiểu trả về của số CriteriaQuery
được đề cập. Ví dụ, ví dụ đầu tiên trong câu trả lời này có thể được viết lại bằng cách sử dụng multiselect()
như sau.
CriteriaQuery<EmployeeDetails> q = cb.createQuery(EmployeeDetails.class);
Root<Employee> root = q.from(Employee.class);
q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary));
Kể từ khi loại kết quả là EmployeeDetails
, phương pháp multiselect()
giải thích về dự báo đối số của nó như các đối số nhà xây dựng của EmployeeDetails
.
Lưu ý rằng một cấu trúc như thế này, cb.construct(EmployeeDetails.class, root.get(Employee_.empName), root.get(Employee_.salary)
như được sử dụng trong ví dụ đầu tiên, không phải được sử dụng trong ví dụ trước sử dụng multiselect()
tự động diễn giải thuật ngữ đối số dựa trên kiểu trả về của truy vấn và gọi hàm tạo trong lớp kết quả - EmployeeDetails
.
Nếu truy vấn đã được xác định để trả lại một Tuple
(hoặc một danh sách các Tuple
s), phương pháp multiselect()
với những lập luận chính xác cùng sẽ tạo ra Tuple
trường hợp thay vì như hình dưới đây.
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Employee> root = q.from(Employee.class);
q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary));
Không cần phải đề cập đến nhưng điều tương tự cũng có thể được viết lại để trả lại một Object[]
(hoặc một danh sách các Object[]
s).
CriteriaQuery<Object[]> q = cb.createQuery(Object[].class);
Root<Employee> root = q.from(Employee.class);
q.multiselect(root.get(Employee_.empName), root.get(Employee_.salary));
Trong cả hai trường hợp, phương pháp muliselect()
tự động giải thích về dự báo đối số của nó dựa trên các kiểu trả về của truy vấn như đã nói trước đây là Tuple
và Object[]
tương ứng.
Nó cũng cần lưu ý rằng EcliseLink có bug mà vẫn còn được cố định trong khi lấy một thuật ngữ Boolean
lựa chọn duy nhất trong cách này sử dụng multiselect()
như trong this question.
Tùy thuộc vào nhà cung cấp JPA khác nhau, hành vi của các phương pháp multiselect()
trở nên thú vị hơn với Object
như một loại kết quả,
- Nếu phương pháp
multiselect()
được sử dụng có thời hạn lựa chọn duy nhất, kiểu trả về là chính thuật ngữ được chọn. Tuy nhiên, - Nếu phương pháp
multiselect()
có chứa nhiều cụm từ nhập/cụm từ lựa chọn/thuật ngữ dự đoán, loại kết quả làObject[]
.
Tôi không chắc chắn về các nhà cung cấp khác nhau nhưng các điều khoản lựa chọn theo quy định của phương pháp multiselect()
có thể không phải là mảng hoặc tập hợp (hoặc cụm từ có giá trị tuple). Các thuật ngữ phức hợp duy nhất có thể được cho phép dưới dạng đối số multiselect()
là các đối số được tạo bởi phương thức construct()
về cơ bản đại diện cho một phần tử duy nhất.
Ngoài các cấu trúc trên, việc sử dụng CriteriaQuery#select(Selection<? extends T> selection)
là khá phổ biến khi sử dụng vô hướng/nhóm/tổng hợp/đơn có giá trị chức năng như count()
, max()
, min()
vv và phụ truy vấn. Việc sử dụng các truy vấn phụ được loại trừ khỏi câu trả lời này cho ngắn gọn.
A
Selection
xác định những gì được chọn bởi truy vấn. Lựa chọn có thể là bất kỳ biểu thức đối tượng, biểu thức thuộc tính, hàm, lựa chọn phụ, hàm tạo hoặc hàm tổng hợp. Bạn có thể xác định bí danh cho một sốSelection
bằng cách sử dụng API bí danh().CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); // Count the total employees CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(); Root employee = criteriaQuery.from(Employee.class); criteriaQuery.select(criteriaBuilder.count(employee)); //<------ Query query = entityManager.createQuery(criteriaQuery); Long result = query.getSingleResult(); // Maximum salary CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(); Root employee = criteriaQuery.from(Employee.class); criteriaQuery.select(criteriaBuilder.max(employee.get("salary")); //<------ Query query = entityManager.createQuery(criteriaQuery); Long result = query.getSingleResult();
http://en.wikibooks.org/wiki/Java_Persistence/Criteria#Selection
Cảm ơn Tiny, Nhưng tôi vẫn chưa rõ về nó. Bất kỳ URL nào để tham khảo đều có thể giúp ích rất nhiều. – Prem
[Tham khảo JBoss] (https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html), [Hướng dẫn Oracle - Java EE 7] (http://docs.oracle. com/javaee/7/tutorial/persistence-criteria.htm), [JPA WikiBook] (http://en.wikibooks.org/wiki/Java_Persistence/Criteria). – Tiny
Bạn có tìm thấy một số khó khăn trong việc hiểu các đoạn mã hoặc thông tin văn bản dài không? Đó là một ví dụ đơn giản, đơn giản và bị cắt giảm được lặp đi lặp lại nhiều lần. Tôi đã trả lời dựa trên một blog mà tôi nhớ. Tôi dự định trích dẫn nhiều thứ từ blog đó nhưng rất tiếc, tôi không thể tìm thấy liên kết đó ngay bây giờ.Nhân tiện, câu hỏi cụ thể được trả lời bằng một câu lệnh duy nhất, "* Một thực thể bền vững ứng cử viên chính nó như là thuật ngữ chiếu duy nhất được suy diễn ngầm. *" – Tiny
- 1. Subquery trong chọn khoản với API JPA Tiêu chuẩn
- 2. JPA/Tiêu chuẩn API - Giống như & vấn đề bình đẳng
- 3. Viết mệnh đề HQL sử dụng Tiêu chí Hibernate API
- 4. Làm thế nào để sử dụng JPA Tiêu chuẩn API khi tham gia nhiều bảng
- 5. Hibernate Criteria API tương đương với mệnh đề lựa chọn HQL?
- 6. Hướng dẫn Tiêu chuẩn JPA
- 7. Cách sử dụng API tiêu chí JPA trong JOIN
- 8. Ví dụ sử dụng countDistinct trong một JPA truy vấn Tiêu chuẩn API
- 9. ORDER BY sử dụng Tiêu chuẩn API
- 10. JPA - Tiêu chuẩn Query - Tìm kiếm Integer sử dụng "like"
- 11. JPA nhóm Tiêu chuẩn truy vấn bằng cách sử dụng chỉ id
- 12. Sublime Tiêu đề lựa chọn 2 văn bản trong thẻ
- 13. Chọn các cột cụ thể trong jpa 2 API tiêu chí?
- 14. Tiêu chuẩn JPA truy vấn riêng biệt
- 15. Cách sử dụng JPA Enum trong một mệnh đề JPQL ở đâu?
- 16. NPE trong dữ liệu Spring JPA với mệnh đề IN
- 17. Cách sử dụng mệnh đề IN trong iBATIS?
- 18. Chọn MAX timestamp với Tiêu chuẩn JPA2 API
- 19. Thêm tiêu đề khi sử dụng httpClient.GetAsync
- 20. Chỉ sử dụng biến trong mệnh đề where nếu NOT trống? Một loại mệnh đề động ở đâu?
- 21. Khi nào bạn nên sử dụng JCR và khi nào bạn nên sử dụng JPA/RDBMS?
- 22. Truy vấn Tiêu chuẩn Văn bản của Oracle trong JPA
- 23. Có thể vượt qua bất kỳ cột khác sau khi mệnh đề where trong lựa chọn công bố Cassandra
- 24. Làm thế nào để lựa chọn chiến lược thế hệ id khi sử dụng JPA và Hibernate
- 25. JPA tiêu chí truy vấn API thuộc tính lớp con
- 26. Cách sử dụng cột tạm thời trong mệnh đề where
- 27. SQLiteDatabase - Cách sử dụng mệnh đề where?
- 28. API tiêu chí JPA: LEFT JOIN cho các mối quan hệ tùy chọn
- 29. Sử dụng mệnh đề WHERE tổng thể khi sử dụng UNIONS trong sql
- 30. Sử dụng tiêu đề phần trong Sendgrid
'cq.select (root); 'được suy ra trong tiêu chuẩn JPA sẽ chọn tất cả các lĩnh vực trong thực thể liên quan (ies) và do đó từ bảng cơ sở dữ liệu tương ứng (s). Tuy nhiên, bạn cần phải rõ ràng, khi bạn muốn chọn một vài trong số họ. – Tiny