2009-05-07 37 views
14

Tôi đang trong quá trình thay đổi lớp DAO của mình từ việc sử dụng API Hibernate để sử dụng triển khai API JPA thuần túy. Có vẻ như phương pháp được đề xuất là sử dụng createNamedQuery từ trình quản lý thực thể. Các truy vấn được đặt tên được lưu trữ trong các chú thích trong các lớp mô hình/thực thể. Điều này không có ý nghĩa với tôi. Tại sao bạn định nghĩa các truy vấn JPA trong các đối tượng mô hình nhưng sử dụng chúng trong các DAO. Nó sẽ không có ý nghĩa hơn để chỉ sử dụng createQuery từ bên trong DAO chính nó và xác định các truy vấn trong DAO hoặc thậm chí chỉ cần xác định các truy vấn được đặt tên trong DAO chính nó?JPA lý do tại sao sử dụng createNamedQuery

Đối với những người bạn đã triển khai lớp DAO của bạn bằng cách sử dụng API JPA, bạn đã xác định các truy vấn của mình như thế nào?

Trả lời

12

Tôi sử dụng truy vấn được đặt tên.

Có hai lý do để làm như vậy:

  1. Nó đặt chúng trong một vị trí trung tâm hơn là rải rác trong mã với createQuery ngẫu nhiên() gọi; và
  2. Quá trình tạo có thể xác thực các truy vấn (thực sự hữu ích).
+7

Tại sao vị trí trung tâm phải là đối tượng mô hình so với DAO thực sự đang sử dụng nó? – Ruggs

+2

Tôi quên đề cập đến những truy vấn được đặt tên mà tôi thường đưa vào thực thể. Nếu truy vấn vượt qua một số thực thể bạn chỉ cần chọn một thực thể phù hợp nhất. – cletus

6

Tôi đã có trải nghiệm hoàn toàn trái ngược với một trong những dòng sản phẩm - Tôi thấy không có lợi ích và cũng thấy chúng khó xử dụng. Các truy vấn tầm thường sẽ không tạo ra sự khác biệt nào để xác định, nhưng các truy vấn không tầm thường thường khó liên kết với bất kỳ thực thể đơn lẻ nào nhưng dễ dàng với phương pháp hướng nghiệp vụ.

Nếu bạn sử dụng cơ sở hạ tầng ít phức tạp hơn trong DAO (để sử dụng lại và nhất quán) thì việc sử dụng truy vấn được đặt tên có xu hướng làm phức tạp cả triển khai và khả năng đọc mà không có lợi ích rõ ràng.

Xác thực truy vấn bằng quá trình tạo âm thanh thú vị - Tôi muốn biết nhiều hơn ý nghĩa của nó ... Truy vấn của tôi để lại ít lỗi vì mỗi phương pháp DAO là đơn vị được kiểm tra nhiều nhất.

+1

Tôi cũng tìm thấy chúng vụng về, đó là lý do tại sao tôi đề xuất các câu hỏi. Có một vị trí trung tâm cho các truy vấn có ý nghĩa cho khả năng bảo trì tuy nhiên tôi không biết nếu đặt chúng trong đối tượng mô hình có ý nghĩa hay không. Nếu tôi duy trì một DAO tôi lần đầu tiên đi đến phương pháp DAO mà cần phải được cập nhật, bây giờ tôi phải đi đến đối tượng mô hình chỉ để bắt đầu xem xét các truy vấn. – Ruggs

+0

Xác thực thực sự khá tốt. Tôi sử dụng nhật thực cho sự phát triển của mình và khi tôi viết một vài truy vấn, tôi đã tắt từ khóa AS và tôi đã nhận được lỗi trong khi xây dựng. – Ruggs

+0

Tôi nên thêm rằng tôi thường không sử dụng chúng cho các truy vấn tầm thường (ví dụ "chọn p từ bên p nơi name =: name"), chỉ các truy vấn phức tạp hơn. – cletus

2

Không chỉ sử dụng truy vấn được đặt tên ở mọi nơi, có trường hợp chúng không thích hợp, chẳng hạn như khi truy vấn hiếm khi được sử dụng thì có thể hiệu quả hơn khi được xây dựng khi cần thiết.

Truy vấn được đặt tên có ý nghĩa hơn khi truy vấn phức tạp và được thực hiện thường xuyên.

[Cập nhật]

Bạn có thể viết các truy vấn tên ở bản đồ, để thay thế.

+0

Tại sao tần suất truy vấn được thực hiện làm cho nó trở thành một ứng cử viên tốt hơn để trở thành truy vấn được đặt tên. – Ruggs

+0

Các truy vấn được đặt tên được phân tích cú pháp một lần và được sử dụng vĩnh viễn. Vì vậy, nếu chúng ta viết một truy vấn sai nó ném một ngoại lệ ngay lập tức. Các truy vấn mà bạn xây dựng trong mã được phân tích tất cả thời gian trừ khi được lưu trong bộ nhớ cache. –

+0

Nhân tiện, liên kết được đề xuất giống nhau. http://www.oracle.com/technology/products/ias/toplink/doc/1013/main/_html/qryun008.htm –

10

Bạn có thể xem Spring Data JPA. Nó cho phép bạn chỉ định nghĩa một giao diện và thực thi các truy vấn mà không cần phải thực hiện việc thực hiện một cách thủ công.

Entity:

@Entity 
@NamedQuery(id="User.findByLastname" query="from User u where u.lastname = ?1") 
public class User implements Persistable<Long> { 

    @Id 
    private Long id; 
    private String username; 
    private String lastname; 
    private int age; 
} 

Repository:

public interface UserRepository extends CrudRepository<User, Long> { 

    // Will trigger the NamedQuery due to a naming convention 
    List<User> findByLastname(String lastname); 

    // Will create a query from the methodname 
    // from User u where u.username = ? 
    User findByUsername(String username); 

    // Uses query annotated to the finder method in case you 
    // don't want to pollute entity with query info 
    @Query("from User u where u.age > ?1") 
    List<User> findByAgeGreaterThan(int age); 
} 

Setup:

EntityManager em = Persistence.getEntityManagerFactory().createEntityManager(); 
JpaRepositoryFactory factory = new JpaRepositoryFactory(em); 

UserRepository repository = factory.getRepository(UserRepository.class); 

Như bạn thấy, bạn có thể lựa chọn giữa nhiều cách khác nhau để lấy được các truy vấn được thực hiện từ phương pháp này .Trong khi phát trực tiếp từ tên phương thức là khả thi đối với các truy vấn đơn giản, bạn có thể chọn giữa số @NamedQuery (tiêu chuẩn JPA) hoặc @Query (chú thích JPA dữ liệu mùa xuân) phụ thuộc vào mức độ bạn muốn tuân theo các tiêu chuẩn.

JPA dữ liệu mùa xuân cung cấp cho bạn hỗ trợ ở các góc khác nhau của triển khai lớp truy cập dữ liệu, cho phép cung cấp triển khai tùy chỉnh cho các phương pháp và tích hợp độc đáo với Spring.

+0

Câu hỏi đặt ra là về các giải pháp JPA, không phải API kiên trì để sử dụng. –

+3

Câu hỏi đặt ra là "Đối với những người bạn đã triển khai lớp DAO của bạn bằng cách sử dụng API JPA, bạn đã xác định các truy vấn của mình như thế nào?" và tôi chỉ muốn chỉ ra một giải pháp khả thi. Hades cung cấp một giải pháp thay thế dễ tiếp cận hơn để sử dụng EntityManager đơn giản và dựa trên JPA đơn giản, vì vậy tôi không nhận được điểm của bạn thực sự. –

+1

Tôi nghĩ câu trả lời và lý luận của Oliver là hợp lý. Cá nhân tôi nghĩ rằng ví dụ của ông về Hades là rất thú vị và trả lời cho câu hỏi. Trên thực tế, tôi nghĩ rằng tôi sẽ có một cái nhìn sâu sắc hơn về khuôn khổ ... :) –

2

Embrace sức mạnh của và :) Nếu bạn có truy vấn có ý nghĩa khi đưa vào mô hình, hãy làm như vậy. Nếu không, đừng. Nó có thể còn tốt hơn để hỏi "Tại sao bạn viết DAO với JPS?" Nếu câu trả lời là "Cô lập mã của tôi từ cơ sở dữ liệu." Điều này được thực hiện bởi thư viện thực hiện JPA. Nếu câu trả lời là "để cô lập mã của tôi khỏi những thay đổi theo cách tôi tồn tại mọi thứ", thì JPA thực hiện điều đó bằng cách cho phép bạn có các triển khai khác nhau. Tôi sử dụng các đối tượng truy vấn cho các truy vấn phức tạp và vẫn sử dụng các truy vấn được đặt tên nếu có thể và tôi thích thực tế các truy vấn được đặt tên được biên dịch và tôi tìm thấy các lỗi trong chúng nhanh hơn nhiều. Tôi không có lớp DAO.

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