2010-10-08 34 views
43

Theo câu hỏi trước đây của tôi, DAO and Service layers (JPA/Hibernate + Spring), tôi quyết định chỉ sử dụng một DAO duy nhất cho lớp dữ liệu của tôi (ít nhất là ở đầu) trong một ứng dụng sử dụng JPA/Hibernate, Mùa xuân và Wicket. Việc sử dụng các phương pháp CRUD chung đã được đề xuất, nhưng tôi không chắc chắn cách thực hiện điều này bằng cách sử dụng JPA. Bạn có thể vui lòng cho tôi một ví dụ hoặc chia sẻ liên kết về vấn đề này không?Phương pháp DAO & CRUD đơn lẻ (JPA/Hibernate + Spring)

Trả lời

84

Dưới đây là một giao diện ví dụ:

public interface GenericDao<T, PK extends Serializable> { 
    T create(T t); 
    T read(PK id); 
    T update(T t); 
    void delete(T t); 
} 

Và một thực hiện:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> { 

    protected Class<T> entityClass; 

    @PersistenceContext 
    protected EntityManager entityManager; 

    public GenericDaoJpaImpl() { 
     ParameterizedType genericSuperclass = (ParameterizedType) getClass() 
      .getGenericSuperclass(); 
     this.entityClass = (Class<T>) genericSuperclass 
      .getActualTypeArguments()[0]; 
    } 

    @Override 
    public T create(T t) { 
     this.entityManager.persist(t); 
     return t; 
    } 

    @Override 
    public T read(PK id) { 
     return this.entityManager.find(entityClass, id); 
    } 

    @Override 
    public T update(T t) { 
     return this.entityManager.merge(t); 
    } 

    @Override 
    public void delete(T t) { 
     t = this.entityManager.merge(t); 
     this.entityManager.remove(t); 
    } 
} 
+2

Làm thế nào sẽ phù hợp này với thực thể slsb và pojo (biểu diễn các bảng db)? – NimChimpsky

+3

Câu trả lời hay. Chỉ cần một vài ý kiến: Tôi thay vì vượt qua các lớp như là một tham số trong phương thức constructor (thay vì một unchecked cast); tham số t trong phương thức xóa không nên được gán lại và lớp sẽ tốt hơn là trừu tượng. – megathor

+0

Cảm ơn !!!!!!!! RẤT NHIỀU! – verystrongjoe

2

nếu bạn đang tìm kiếm một thực hiện của bên thứ ba, bạn có thể kiểm tra http://www.altuure.com/projects/yagdao/. nó là một khung công tác DAO chung dựa trên nnotation hỗ trợ JPA và hibernate

5

Tôi đang tìm kiếm điều tương tự này. Tôi đã tìm thấy chính xác điều đó - dự án JPA Spring-Data được cung cấp bởi SpringSource. Đây là một cổng mã từ Hades và hiện tại (đầu năm 2011) đã bị mùa xuân nuốt và tích hợp tốt hơn. Nó cho phép bạn sử dụng một dao đơn (SimpleJpaRepository) với một tạo tĩnh, hoặc mở rộng lớp JpaRepository cơ sở để tạo ra bất kỳ dao cụ thể đối tượng nào với các phương thức CRUD + đã sẵn sàng. Cũng cho phép grails như truy vấn chỉ bằng cách sử dụng tên params như tên của method- trong giao diện (không cần thực hiện)! findByLastname(String lastName); Trông rất hứa hẹn - là một phần của dự án Spring chắc chắn sẽ đảm bảo một số tương lai cho nó. Tôi đã bắt đầu triển khai dự án này trong dự án sắp tới của tôi ngay bây giờ.

14

Dựa trên bài viết Don't repeat the DAO chúng tôi đã sử dụng loại kỹ thuật này trong nhiều năm. Chúng tôi luôn đấu tranh với các vấn đề với các mẫu của chúng tôi sau khi chúng tôi nhận ra rằng chúng tôi đã phạm một sai lầm lớn.

Bằng cách sử dụng công cụ ORM như Hibernate hoặc JPA, bạn sẽ không phải nghĩ riêng DAO và lớp Dịch vụ. Bạn có thể sử dụng EntityManager từ các lớp dịch vụ của bạn khi bạn biết vòng đời của các giao dịch và logic của các lớp thực thể của bạn ở đó.

Bạn có tiết kiệm được chút thời gian nếu bạn gọi myDao.saveEntity thay vì chỉ đơn giản là entityManager.saveEntity? Bạn sẽ có một lớp dao không cần thiết mà không làm gì khác ngoài việc sẽ là một trình bao bọc xung quanh EntityManager. Đừng ngại viết các lựa chọn trong các lớp dịch vụ của bạn với sự trợ giúp của EntityManager (hoặc phiên trong hibernate).

Một lưu ý nữa: Bạn nên xác định đường viền của lớp dịch vụ và không cho phép người lập trình quay lại hoặc đợi các lớp Thực thể. Các lập trình viên lớp UI hoặc WS không nên biết gì về các lớp thực thể chỉ về DTO-s. Các đối tượng thực thể có vòng đời mà hầu hết các lập trình viên không biết. Bạn sẽ có vấn đề thực sự nghiêm trọng nếu bạn lưu trữ một đối tượng thực thể trong dữ liệu phiên và cố gắng cập nhật nó trở lại cơ sở dữ liệu giây hoặc vài giờ sau đó. Vâng, bạn có thể sẽ không làm điều đó, nhưng một lập trình viên của giao diện người dùng biết các loại tham số và kiểu trả về của lớp dịch vụ của bạn sẽ chỉ làm để lưu một số dòng mã.

+0

Quản lý giao dịch được chú thích trong EJB ?! Mặc dù bạn có thể cần DAO phức tạp hơn nhiều, mà sẽ không còn chung chung nữa, nhưng dù sao đi nữa. Tôi vẫn thấy phương pháp này có thể hữu ích trong các trường hợp cụ thể. –

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