2011-04-03 9 views
7

Tôi sử dụng các truy vấn HQL trong Hibernate và chỉ cần tự hỏi, nếu tôi có thể tăng hiệu suất của các truy vấn sử dụng lại ứng dụng của mình.Sử dụng lại các truy vấn trong Hibernate

Thông thường, bạn phải tạo một đối tượng truy vấn mới cho mỗi phiên:

Session session; 
Query q1 = session.createQuery("select a from Article a where id=:id"); 
q1.setInteger("id",123); 
List result = q1.list(); 

Bây giờ tôi có thắc mắc tương đối phức tạp trong HQL, mà tôi không muốn đã phân tích hơn và hơn nữa. Có cách nào để tạo truy vấn và sử dụng lại nó trong một phiên khác không? Như thế này:

Session session; 
Query q2 = q1.reattach(); 
q2.setInteger("id",123); 
List result = q2.list(); 

Nếu Hibernate sử dụng câu lệnh chuẩn bị, đây sẽ là hiệu suất đáng chú ý, đặc biệt là kết hợp với ConnectionPool lưu trữ các câu lệnh chuẩn bị.

EDIT: Sử dụng lại truy vấn trong Hibernate thường không cần thiết, vì kế hoạch truy vấn đã được lưu trong bộ nhớ cache QueryPlanCache. Các truy vấn được đặt tên cũng không cung cấp bất kỳ cải tiến nào nữa, vì chúng chỉ được sử dụng để tra cứu chuỗi truy vấn và không có kế hoạch nào được liên kết với chúng.

Để kết luận: Không có sử dụng trong việc sử dụng lại Truy vấn trong Hibernate. Chỉ cần chắc chắn sử dụng các truy vấn parametrized luôn luôn, vì vậy giữ cho kế hoạch lưu trữ nhỏ.

+0

@allingeek: Chính xác thì sao? Chỉ cần mở QueryPlanCache từ nguồn Hibernate. Hay ý bạn là gì? – Daniel

+0

Điều tôi thực sự tìm kiếm là tái sử dụng PreparedStatement. Đã xóa cấu hình bộ nhớ cache của câu lệnh trong c3p0 dựa trên câu hỏi của bạn và lưu ngày đó. Cảm ơn. – allingeek

Trả lời

4

Bạn có thể sử dụng 'Query Đặt tên': Chú thích lớp Entity của bạn như

@Entity 
@NamedQuery(name="Article.findById", query="select a from Article a where id=:id")  
public class Article{ ... 

và sau đó nó sẽ được phân tích một lần lúc khởi động, bất cứ khi nào bạn muốn sử dụng nó, bạn chỉ cần gọi:

session.getNamedQuery("Article.findById") 
     .setInteger("id",123); 
+1

Đã chấp nhận, mặc dù vô dụng :). Xem chỉnh sửa của tôi cho câu hỏi của tôi. – Daniel

0

Truy vấn được đặt tên là described by Kiavash thực hiện những gì bạn đang yêu cầu nhưng tôi nghi ngờ rằng nó cung cấp cho bạn bất kỳ loại tăng hiệu suất đáng kể nào.

Báo cáo chuẩn bị được sử dụng nếu cơ sở dữ liệu của bạn hỗ trợ chúng bất kể bạn có đang sử dụng Truy vấn được đặt tên của Hibernate hay không. Hầu hết bạn đang tiết kiệm được sự cố khi phân tích cú pháp truy vấn HQL. Truy vấn được đặt tên được dự định để sử dụng lại mã.

+1

Đây chính là ý định của tôi. Tôi đã sử dụng các câu lệnh đã chuẩn bị trong cơ sở dữ liệu và biết một phần lớn thời gian cpu còn lại là chi tiêu cho HQL của truy vấn. – Daniel