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);
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 Clause | Criteria API Interface | Method |
---|---|---|
SELECT | CriteriaQuery | select() |
Subquery | select() | |
FROM | AbstractQuery | from() |
WHERE | AbstractQuery | where() |
ORDER BY | CriteriaQuery | orderBy() |
GROUP BY | AbstractQuery | groupBy() |
HAVING | AbstractQuery | having() |
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.