Thứ Bảy, 7 tháng 1, 2017

Criteria API

I.Định Nghĩa

Trước khi các ngôn ngữ như JP QL đã trở thành tiêu chuẩn, phương pháp phổ biến nhất để xây dựng các truy vấn trongnhiều nhà cung cấp bền bỉ đã được thông qua một API lập trình. Khung truy vấn trong EclipseLink, cho ví dụ là cách hiệu quả nhất để thực sự mở khóa toàn bộ sức mạnh của công cụ truy vấn của nó. Và, ngay cả với các đời của JP QL, API lập trình đã vẫn còn được sử dụng để cung cấp cho truy cập vào các tính năng chưa được hỗ trợ bởi ngôn ngữ truy vấn chuẩn.

JPA 2.0 giới thiệu một tiêu chuẩn API mới để xây dựng các truy vấn chuẩn hóa nhiều tính năng mà tồn tại trong các sản phẩm kiên trì độc quyền chương trình. Không chỉ là một bản dịch nghĩa đen JP QL để giao diện lập trình, nó cũng thông qua thực hành lập trình tốt nhất của các mô hình độc quyền, chẳng hạn như phương pháp xâu chuỗi, và tận dụng đầy đủ các tính năng ngôn ngữ lập trình Java.

II.Chi Tiết
SELECT e FROM Employee e WHERE e.name = ‘John Smith’
Và đây là các truy vấn tương đương xây dựng bằng cách sử dụng tiêu chí API :
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery c = cb.createQuery(Employee.class);
Root emp = c.from(Employee.class);
c.select(emp).where(cb.equal(emp.get(“name”), “John Smith”));
  • Search employee sử dung jpql
@Stateless
public class SearchService {
@PersistenceContext(unitName = "EmployeeHR")
EntityManager em;
public List findEmployees(String name, String deptName,
String projectName, String city) {
StringBuffer query = new StringBuffer();
query.append("SELECT DISTINCT e ");
query.append("FROM Employee e LEFT JOIN e.projects p ");
query.append("WHERE ");
List criteria = new ArrayList();
if (name != null) {
criteria.add("e.name = :name");
}
if (deptName != null) {
criteria.add("e.dept.name = :dept");
}
if (projectName != null) {
criteria.add("p.name = :project");
}
if (city != null) {
criteria.add("e.address.city = :city");
}
if (criteria.size() == 0) {
throw new RuntimeException("no criteria");
}
for (int i = 0; i < criteria.size(); i++) {
if (i > 0) {
query.append(" AND ");
}
query.append(criteria.get(i));
}
Query q = em.createQuery(query.toString());
if (name != null) {
q.setParameter("name", name);
}
if (deptName != null) {
q.setParameter("dept", deptName);
}
if (projectName != null) {
q.setParameter("project", projectName);
}
if (city != null) {
q.setParameter("city", city);
}
return (List) q.getResultList();
}
}
  • Search Employee sử dụng  Criteria API
@Stateless
public class SearchService {
@PersistenceContext(unitName = "EmployeeHR")
EntityManager em;
public List findEmployees(String name, String deptName,
String projectName, String city) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery c = cb.createQuery(Employee.class);
Root emp = c.from(Employee.class);
c.select(emp);
c.distinct(true);
Join<Employee, Project> project
= emp.join("projects", JoinType.LEFT);
List criteria = new ArrayList();
if (name != null) {
ParameterExpression p
= cb.parameter(String.class, "name");
criteria.add(cb.equal(emp.get("name"), p));
}
if (deptName != null) {
ParameterExpression p
= cb.parameter(String.class, "dept");
criteria.add(cb.equal(emp.get("dept").get("name"), p));
}
if (projectName != null) {
ParameterExpression p
= cb.parameter(String.class, "project");
criteria.add(cb.equal(project.get("name"), p));
}
if (city != null) {
ParameterExpression p
= cb.parameter(String.class, "city");
criteria.add(cb.equal(emp.get("address").get("city"), p));
}
if (criteria.size() == 0) {
throw new RuntimeException("no criteria");
} else if (criteria.size() == 1) {
c.where(criteria.get(0));
} else {
c.where(cb.and(criteria.toArray(new Predicate[0])));
}
TypedQuery q = em.createQuery(c);
if (name != null) {
q.setParameter("name", name);
}
if (deptName != null) {
q.setParameter("dept", deptName);
}
if (project != null) {
q.setParameter("project", projectName);
}
if (city != null) {
q.setParameter("city", city);
}
return q.getResultList();
}
}
JP QL ClauseCriteria API InterfaceMethod
SELECTCriteriaQueryselect()
Subqueryselect()
FROMAbstractQueryfrom()
WHEREAbstractQuerywhere()
ORDER BYCriteriaQueryorderBy()
GROUP BYAbstractQuerygroupBy()
HAVINGAbstractQueryhaving()
III.Đánh Giá

Các API Tiêu chuẩn được sử dụng để xác định các truy vấn cho các entity và persistent state của nó bằng cách tạo ra query-defining objects. Tiêu chuẩn truy vấn được viết bằng ngôn ngữ lập trình API Java, là typesafe, và linh hoạt. truy vấn như vậy làm việc được với bất kể là data store.

IV.Tổng Kết

Trong điều tra các API tiêu chuẩn, chúng ta bắt đầu với khái niệm JP QL và tìm cách vẽ song song giữa các ngôn ngữ truy vấn và các API tiêu chí. Chúng tôi nhìn vào cách xây dựng từng điều khoản của một truy vấn với các API tiêu chuẩn và giải quyết một số vấn đề phức tạp hơn mà các nhà phát triển gặp phải.

Chúng ta có thể tìm hiểu các API metamodel và biết làm thế nào nó có thể được sử dụng để tạo các truy vấn mạnh mẽ đánh máy với các API tiêu chí. Chúng tôi nhìn vào lập trình với các API metamodel sử dụng cả hai giao diện thời gian chạy và thông qua các lớp học tạo ra một thực metamodel kinh điển.

Cuối cùng chúng tôi đã thảo luận về những ưu điểm của phương pháp tiếp cận khác nhau để truy vấn xây dựng sử dụng JP QL,

API là rất khác nhau từ các ngôn ngữ truy vấn JP QL, ngữ nghĩa cơ bản gần như giống nhau và chuyển đổi giữa hai là tương đối dễ dàng một khi bạn nhận được hang của API mã hóa mẫu.

Không có nhận xét nào:

Đăng nhận xét