2012-09-24 97 views
5

目前我正在爲我的工作項目使用struts2框架,並且在設計我的DAO類時,我有一個想法來改進設計模式。Java EE DAO/DTO(數據傳輸對象)設計模式

在我的搜索功能,我有3個類型的搜索

  1. 搜索帶有一個參數,而另一方面,
  2. 搜索與多個參數,
  3. 搜索不帶參數。

我的問題是,做DAO方法的最佳方法是什麼?

在我struts2的方法

,我有

public String execute() { 

    //assuming these are passed in from JSP 
    if ("searchByAnId".equals(paramSearch)) 
    { 
     List<DTO> datalist = this.someDao.implementList(theIdParam); 

    } else if("searchByAnOtherParam".equals(paramSearch)) 
    { 
     List<DTO> datalist = this.someDao.implementAnotherList(param1, param2, param3, param4) 
     // more params 
    } else 
    { 
     List<DTO> datalist = this.someDao.implementListAll(); 
    }  

    return "success"; 
} 

我讀設計模式,如工廠方法,裝飾方法,觀察方法,但我不知道哪一個是最合適的人(或其他沒有第三方插件的)適合這個?

+1

在我的項目中,我創建了一個SearchCriteria對象,其中包含DAO所屬的表的列。然後,您在此SearchCriteria對象中提供詳細信息,並在您的DAO中執行基於它的搜索。 – Atul

+0

是的,我不認爲有這樣的具體設計模式。 – Atul

回答

6

我通常傾向於創建的常見到我的所有域實體的方法,如定義一個基本的DAO接口:

// marker interface 
public interface DomainEntity extends Serializable { } 

// common dao methods 
public interface DAO<T extends DomainEntity> { 
    public T findById(Long id); 
    public List<T> findAll(); 
    public T save(T entity); 
    public boolean update(T entity); 
    public boolean delete(T entity); 
} 

,然後根據我的要求,提供了一種或多種實現:

// implementation of common dao methods using JPA 
public class JpaDAO<T> implements DAO<T> { 

    private EntityManager em; 

    public JpaDao(EntityManager em) { this.em = em; } 

    // Default implementations using JPA... 
} 

// implementation of common dao methods using JDBC 
public class JdbcDAO<T> implements DAO<T> { 

    private Connection conn; 

    public JdbcDao(Connection conn) { this.conn = conn; } 

    // Default implementations using JDBC 
} 

現在,假設我有以下的人等級:

public class Person implements DomainEntity { 
    private Long id; 
    private String firstName; 
    private String lastName; 

    // getters/setters... 
} 

我首先定義一個通用的PersonDAO接口,像這樣:

public interface PersonDAO implements DAO<Person> { 
    public List<Person> findByFirstName(String name); 
    public List<Person> findByLastName(String name); 
} 

注意,在我上面的具體實體DAO接口,我只包括了額外的方法所特有的我域實體。常用方法由超級接口繼承,並使用泛型將其參數化爲我的域實體。

現在,最後剩下的就是定義我的實體的具體方法不同的實現,就像這樣:

package mypackage.daos.jpa; 

public class PersonDAOImpl extends JpaDAO<Person> implements PersonDAO { 
    // here i implement only the entity specific dao methods 
    // defined in the last interface. 
} 

如果我還需要提供一個可選擇的DAO實現(亦即基於JDBC而不是JPA)它的那麼容易,因爲創建第二類(最好是在一個單獨的包):

package mypackage.daos.jdbc; 

public class PersonDAOImpl extends JdbcDAO<Person> implements PersonDAO { 
    // again i only implement the entity specific DAO methods since 
    // defaults have been implemented in the super class... 
} 

關於這樣做的好處是,你可以切換的實現,而不調用代碼會受到影響由:

// a service class that uses my dao 
public class PersonService { 

    private PersonDAO dao; 

    public PersonService(PersonDAO dao) { this.dao = dao } 

    public void doSomethingUseful() { 
    // use the dao here... 
    } 
} 

通常,正確的dao實現(jdbc或jpa)將在創建服務時通過構造函數注入。當然,如果你喜歡,你只能有一個實現(即jpa)。

+0

因此,只需確認「interface PersonDAO」與「DAO 」之間的關係是什麼? 道歉,我在設計模式很糟糕... –

+0

接口DAO是一個類型參數化接口,它定義了所有域實體共有的DAO操作。接口PersonDAO(擴展DAO)包括特定於Person域實體的操作。 –

+0

關於通用PersonDao - 不應該讀'interface PersonDao擴展Dao '而不是'implements'? – Louise