通用道
好吧,对我来说,如果您的 GenericDAO 是“通用的”,那么您可能只需要一个实例,并使用该实例完成所有操作。
我敢肯定,在实例上连接不会打扰您,您会因为重复而生气(我同意您的观点)。
例如,您可以将 Entity 类传递给泛型方法。
- public void save(Class, E...) :让您保存一个或多个 E 类型的实例,E 是您的实体之一。
- public E load(Class, Long id) : 加载一个实体。
...
/** Assuming the entities have a superclass SuperEntity with getIdent(). */
public class GenericDaoImpl implements GenericDao {
/** Save a bunch of entities */
public void save(SuperEntity... entities) {
for(SuperEntity entity : entities) {
getSession().save(entity);
}
}
/** Load any entity. */
public <E extends SuperEntity> E load(Class<E> entityClass, Long ident) {
return (E)getSession().load(entityClass, ident);
}
// other generic methods
}
变体
在我们的应用程序中,我们实际上有一个变体。因为我们对每个 Dao 有很多特定的请求,所以无论如何我们都需要特定的 Dao 类(创建类并连接它),所以为了避免不定义 Dao 的特殊情况,我们立即制作特定的 Dao 类。
编码
但我们绝不会重复代码。我们所有的 Daos 都扩展了 GenericDao,在构造函数中提供了所需的 Class 参数。示例代码(不完整,简单了解一下基本思路):
public abstract class GenericDaoImpl<E extends SuperEntity>
implements GenericDao<E> {
/** Available for generic methods, so it is not a parameter
* for the generic methods. */
private final Class<E> entityClass;
protected GenericDaoImpl(Class<E> entityClass) {
this.entityClass = entityClass;
}
// generic implementation ; can be made efficient, as it may
// send the orders as a batch
public void save(E... entities) {
for(SuperEntity entity : entities) {
getSession().save(entityClass, entity.getIdent());
}
// possibly add flushing, clearing them from the Session ...
}
// other generic methods
}
public class PersonDaoImpl extends GenericDaoImpl<Person>
implements PersonDao {
/** Constructor, instanciating the superclass with the class parameter. */
public PersonDaoImpl() {
super(Person.class);
}
/** Specific method. */
public List<Person> findByAge(int minAge, int maxAge) {
//....
}
}
接线
连接所有的豆子不是致命的。现在有很多自动装配策略,你不必担心。在 Spring http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config中查看它们