Reads:42249Replies:0
A clever BaseDao design
The BaseDao is designed to facilitate our usage and avoid writing many repeated code. Today we will talk about its designing philosophy. We achieve implementation through reflection + generic type + interface-oriented programming. I found a UML diagram on the internet and we will refer to the diagram below to make a simple design with the code. In the code, I use the HibernateTemplate in Spring as the basis. First, I need to design various interfaces and implementation classes according to the UML diagram. The specific interfaces and implementation classes are embodied in code.
You can view the specific implementation of the inheritance and implementation relationships with the help of both the code and UML diagram. ![]() Let’s roughly follow the content in the diagram. First, define an interface BaseDao<T> as the top interface. <span style="font-size:18px;">package pac2; import java.io.Serializable; import java.util.List; /** * Interface * @author admin */ public interface BaseDao<T>{ //Add public void add(T t); //Delete public void delete(T t); //Update public void update(T t); //Query by the ID public T findOne(Serializable id); //Query all public List<T> findAll(); }</span> Next, write another interface implementation class to implement the abstract methods in the interface for direct calls. This implementation class is comparatively difficult. I recommend you refer to and carefully analyze the notes to discover what’s neat in it. Then you can inherit from this class during usage to complete basic addition, deletion, modification and query functions. 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; /** * Interface implementation class * @author admin * */ public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class clazzP; public BaseDaoImpl(){ //Objective: get the actual type parameter //Get the current running object Class clazz = this.getClass(); //Get the parameterized type of the parent class of the current object. Usually we use the type sub-interface ParameterizedType. Type type = clazz.getGenericSuperclass(); ParameterizedType ptype=(ParameterizedType)type; //Get the actual type parameter Type[] types = ptype.getActualTypeArguments(); Class clazzParameter=(Class)types[0]; this.clazzP=clazzParameter; } //Add public void add(T t){ this.getHibernateTemplate().save(t); } //Delete public void delete(T t){ this.getHibernateTemplate().delete(t); } //Update public void update(T t){ this.getHibernateTemplate().update(t); } //Query by the ID public T findOne(Serializable id){ return (T)this.getHibernateTemplate().get(clazzP, id); } //Query all public List<T> findAll(){ return (List<T>) this.getHibernateTemplate().find("from "+clazzP.getSimpleName()); } }</span> Because we are used to the interface-oriented programming, there is another interface CustomerDao interface of the Customer module. <span style="font-size:18px;">package pac2; import pac.entity.Customer; /** * Interface-oriented programming * CustomerDao * @author admin * */ public interface CustomerDao extends BaseDao<Customer> { }</span> At the bottom is the specific implementation class of the dao layer of the Customer module. The inheritance and implementation relationships are in the following code. <span style="font-size:18px;">package pac2; import java.io.Serializable; import java.util.List; import pac.entity.Customer; /** * Specific implementation class of Customer * So we implement the basic addition, deletion, modification and query functions of the interface. * @author admin * */ public class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao { } </span> By now, a BaseDao is complete. We can find that coding is not required in the specific implementation class in the dao layer at last (existing methods in the interface do not need to be coded again, but some special query methods still need coding...) as you can directly call them. This case is true for other modules. It is now much more concise, right? |
|