Java DAO接口/实现拆分层次结构和约定

Java DAO接口/实现拆分层次结构和约定,java,dao,Java,Dao,在尝试实现基本的通用CRUD DAO时,我遇到了一个似乎有点反模式的问题 通用刀 public interface GenericDao<T, PK extends Serializable> { T findOne(final PK id); List<T> findAll(); PK create(final T entity); void update(final T entity); void delete(final T entit

在尝试实现基本的通用CRUD DAO时,我遇到了一个似乎有点反模式的问题

通用刀

public interface GenericDao<T, PK extends Serializable> {

  T findOne(final PK id);

  List<T> findAll();

  PK create(final T entity);

  void update(final T entity);

  void delete(final T entity);

  void deleteById(final PK id);

}
公共接口GenericDao{
T findOne(最终PK id);
列出findAll();
PK创建(最终T实体);
无效更新(最终T实体);
作废删除(最终T实体);
void deleteById(最终PK id);
}
GenericDaoHibernateImpl

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

  @Autowired
  private SessionFactory sessionFactory;
  private Class<T> clazz;

  public GenericDaoHibernateImpl(Class<T> clazzToSet) {
      this.clazz = clazzToSet;
  }

  protected final Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
  }

  @Override
  public T findOne(PK id) {
    return (T) getCurrentSession().get(clazz, id);
  }

  @Override
  public List<T> findAll() {
    return getCurrentSession().createQuery("from " + clazz.getName()).list();
  }

  @Override
  public PK create(T entity) {
    return (PK) getCurrentSession().save(entity);
  }

  @Override
  public void update(T entity) {
    getCurrentSession().update(entity);
  }

  @Override
  public void delete(T entity) {
    getCurrentSession().delete(entity);
  }

  @Override
  public void deleteById(PK id) {
    final T entity = findOne(id);
    delete(entity);
  }
}
公共抽象类GenericDaoHibernateImpl实现GenericDao{
@自动连线
私人会话工厂会话工厂;
私人课堂;
公共GenericDaoHibernateImpl(类clazzToSet){
this.clazz=clazzToSet;
}
受保护的最终会话getCurrentSession(){
返回sessionFactory.getCurrentSession();
}
@凌驾
公共T findOne(主键id){
return(T)getCurrentSession().get(clazz,id);
}
@凌驾
公共列表findAll(){
返回getCurrentSession().createQuery(“from”+clazz.getName()).list();
}
@凌驾
公共主键创建(T实体){
返回(PK)getCurrentSession().save(实体);
}
@凌驾
公共无效更新(T实体){
getCurrentSession().update(实体);
}
@凌驾
公共作废删除(T实体){
getCurrentSession().delete(实体);
}
@凌驾
公共无效deleteById(主键id){
最终T实体=最终完成(id);
删除(实体);
}
}
顾客道

public interface CustomerDao extends GenericDao<Customer, Long> {

  public Customer findByUsername(String username);

}
公共接口CustomerDao扩展了GenericDao{
公共客户findByUsername(字符串用户名);
}
CustomerDaoHibernateImpl

public class CustomerDaoHibernateImpl extends GenericDaoHibernateImpl<Customer, Long> implements CustomerDao {

  public CustomerDaoHibernateImpl() {
    super(Customer.class);
  }

  public Customer findByUsername(String username);
    Criteria criteria =  getCurrentSession().createCriteria(Customer.class);
    criteria.add(Restrictions.eq("username", username));
    return criteria.list();
  }

}
公共类CustomerDaoHibernateImpl扩展了GenericDaoHibernateImpl实现CustomerDao{
公共客户DaoHibernateImpl(){
超级(Customer.class);
}
公共客户findByUsername(字符串用户名);
Criteria=getCurrentSession().createCriteria(Customer.class);
添加(Restrictions.eq(“用户名”,username));
返回条件。list();
}
}
我所指的问题是,在我们特定领域的DAO实现中,我们好像满足/实现了两次GenericDao。一次是在GenericDaoHibernateImpl中,然后是在我们的域DAO接口中,即CustomerDao中。在这里我们必须在声明中详细说明,使用客户和长。 然后我们实现CustomerDaoHibernateImpl,并且再次声明Customer和Long

我做错了什么,因为这似乎不是正确的方法


谢谢

检查这一点

我从未将其视为接口和抽象类扩展/实现公共祖先的反模式。对我来说,客户接口说它需要在通用dao中定义的所有操作。抽象类碰巧说它实现了泛型dao。然后,当您到达客户dao impl时,您表示您实现了客户接口,然后选择通过扩展抽象类来实现该接口。这允许抽象类和客户接口分别增长或更改,如果其中一方不想扩展/实现泛型dao,而另一方想扩展/实现泛型dao。希望这是有道理的


更新:我知道我没有准确地回答您关于必须冗余指定的泛型问题,但希望我的回答能为接口和具有相同祖先接口的抽象类提供一些可信度

这是我不相信使用接口定义DAO类的原因之一。简化模型的一种方法是删除CustomerDAO和GenericDAO接口之间的关系。