在Hibernate框架中使用BaseDao主要的作用是減少冗余代碼,在對Dao的操作中CRUD可以說是最普通最常見的操作了,基本上面對不同的數據表都會有類似的CRUD操作,BaseDao的思想就是把這些冗余的操作抽取出來,所以不需要在spring框架的applicationContext.xml中注冊,這可能是與其他Dao不同之處。作為一個抽象出來的類,使用這個BaseDao可以使我們的代碼更優雅
第一步:和普通Dao一樣,先創建個接口
接口中實現的方法有add(添加),update(更新),delete(刪除),findOne(根據id查詢),findAll(查詢所有)。其實,可以不局限於這幾個方法,只要是Dao中都有的操作,都可以抽取進去,這里只進行基本方法的抽取,這里使用泛型,T代表所有類型。
import java.util.List; public interface BaseDao<T> { public void add(T t); public void update(T t); public void delete(T t); public T findOne(int id); public List<T> findAll(); }
第二步:實現這個接口,寫方法的具體邏輯
這個類還要繼承HibernateDaoSupport,這樣在具體的Dao類中就可以不繼承HibernateDaoSupport,只要繼承於我們編寫BaseDaoImpl就行了。BaseDaoImpl類使用了反射和泛型。
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; import cn.lynu.dao.BaseDao; public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class pClass; public BaseDaoImpl() { //第一步,得到當前運行類的class Class clazz = this.getClass(); //第二步,得到運行類的父類的參數化類型 Type type = clazz.getGenericSuperclass(); ParameterizedType pType=(ParameterizedType) type; //第三步,得到實際類型參數 Type[] types = pType.getActualTypeArguments(); Class tClass= (Class) types[0]; this.pClass=tClass; } //添加 public void add(T t) { this.getHibernateTemplate().save(t); } //更新 public void update(T t) { this.getHibernateTemplate().update(t); } //刪除 public void delete(T t) { this.getHibernateTemplate().delete(t); } //根據Id查詢 public T findOne(int id) { return (T) this.getHibernateTemplate().get(pClass, id); } //查詢所有(使用getSimpleName得到簡稱類名,否則,將會使用類的全路徑從而出錯) public List<T> findAll() { return (List<T>) this.getHibernateTemplate().find("from "+pClass.getSimpleName()); } }
第三步:把所有Dao接口繼承於BaseDao,所有的Dao實現類繼承於BasedaoImpl
看這個Dao接口的實現(別忘了泛型):
再看DaoImpl類的實現(不用繼承HibernateDaoSupport):
注意:這樣我們就不用在UserDao中再寫CRUD和findOne,findAll方法了,但是,我們在使用這些方法時的名稱就是固定的了,不要用錯