BaseDao设计的初衷是为了方便我们的使用,不用写很多的重复的代码,今天就说说它的设计思路。我们就是要用反射加泛型加面向接口编程来实现,从网上找了一个UML图,我们就用下图用代码大体简单设计一下。代码中我用的是基于Spring中的HibernateTemplate模板。首先要做的是按UML图设计出各个接口和实现类,具体的接口和实现类用代码体现出来。
可结合着代码和UML图看其中的继承和实现关系的具体实现
大体按图中的内容写吧,首先定义一个interface BaseDao<T>作为顶层接口
<span style="font-size:18px;">package pac2; import java.io.Serializable; import java.util.List; /** * 接口 * @author admin */ public interface BaseDao<T>{ //添加 public void add(T t); //删除 public void delete(T t); //更新 public void update(T t); //根据id查询 public T findOne(Serializable id); //查询所有 public List<T> findAll(); }</span>接着再写一个接口实现类,来实现接口中的抽象方法,以便拿来直接调用即可。此实现类相对来说比较难理解,建议结合注释好好分析分析,就肯定能看出其中的巧妙之处的。之后在使用的时候继承该实现类就可以完成基本的增删改查功能了。
p<span style="font-size:18px;">ackage pac2; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; /** * 接口实现类 * @author admin * */ public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class clazzP; public BaseDaoImpl(){ //目的:得到实际类型参数 //得到当前运行对象 Class clazz = this.getClass(); //得到当前对象父类的参数化类型,一般使用type子接口ParameterizedType Type type = clazz.getGenericSuperclass(); ParameterizedType ptype=(ParameterizedType)type; //得到实际类型参数 Type[] types = ptype.getActualTypeArguments(); Class clazzParameter=(Class)types[0]; this.clazzP=clazzParameter; } //添加 public void add(T t){ this.getHibernateTemplate().save(t); } //删除 public void delete(T t){ this.getHibernateTemplate().delete(t); } //更新 public void update(T t){ this.getHibernateTemplate().update(t); } //根据id查询 public T findOne(Serializable id){ return (T)this.getHibernateTemplate().get(clazzP, id); } //查询所有 public List<T> findAll(){ return (List<T>) this.getHibernateTemplate().find("from "+clazzP.getSimpleName()); } }</span>
因为我们习惯于面向接口编程,所有再有一个Customer模块的接口interface CustomerDao
<span style="font-size:18px;">package pac2; import pac.entity.Customer; /** * 面向接口编程 * CustomerDao * @author admin * */ public interface CustomerDao extends BaseDao<Customer> { }</span>
最后是Customer模块dao层的具体实现类,继承和实现关系如下代码,
<span style="font-size:18px;">package pac2; import java.io.Serializable; import java.util.List; import pac.entity.Customer; /** * Customer具体实现类 * 这样就实现了基本的增删改查功能,接口中的功能 * @author admin * */ public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao { } </span>
到此,一个BaseDao就算完成了,我们可以发现最后在dao层的具体实现类中根本不用写代码了(接口中有的方法就不用再写了,一些特殊的查询方法还是要写地....),直接调用就ok了!其它模块也如此,这下就简洁很多了吧!