私は通常、次のようなすべてのドメイン エンティティに共通するメソッドの定義を使用して、基本的な 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);
}
次に、要件に基づいて 1 つ以上の実装を提供します。
// 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実装(JPAではなくjdbcに基づくなど)も提供する必要がある場合は、2番目のクラスを作成するのと同じくらい簡単です(できれば別のパッケージで):
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) は、サービスの作成中にコンストラクターを介して挿入されます。もちろん、必要に応じて実装を 1 つだけにすることもできます (つまり、jpa)。