package cn.sxx.dao; import java.util.List; import cn.sxx.model.Dep; import cn.sxx.query.DepQuery; public interface BaseDao<T,Q> { public void save(T t); public void update(T t); public T getObj(Integer id); public void delete(Integer id); public void delete(T t); public List<T> queryObjByCondition(Q q); }
抽取公共Dao的緣由是避免代碼的重複。其實現類:java
package cn.sxx.dao.impl; import cn.sxx.dao.BaseDao; import cn.sxx.model.Dep; import cn.sxx.query.DepQuery; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public abstract class BaseDaoImpl<T,Q> extends HibernateDaoSupport implements BaseDao<T, Q> { @Override public void save(T t) { this.getHibernateTemplate().save(t); } @Override public void update(T t) { this.getHibernateTemplate().update(t); } @Override public T getObj(Integer id) { Class<?> class1 = getGenericClass(); return (T) this.getHibernateTemplate().get(class1, id); } @Override public void delete(Integer id) { T obj = getObj(id); this.getHibernateTemplate().delete(obj); } @Override public List<T> queryObjByCondition(final Q q) { @SuppressWarnings("unchecked") List<?> listT = this.getHibernateTemplate().executeFind(new HibernateCallback<List<T>>() { @Override public List<T> doInHibernate(Session session) throws HibernateException,SQLException { String hql = createHql(q); //建立查詢對象 Query query = session.createQuery(hql); setDynamicParam(query, q); List<T> list = query.list(); return null; } }); /*this.getHibernateTemplate().getSessionFactory().getCurrentSession();*/ return (List<T>) listT; } public Class<?> getGenericClass() { //得到泛型的父類 Type genericSuperclass = this.getClass().getGenericSuperclass(); //把泛型的父類強制轉換成ParameterizedType ParameterizedType pt = (ParameterizedType) genericSuperclass; //根據ParameterizedType得到當前類的全部泛型的類型 Type[] actualTypeArguments = pt.getActualTypeArguments(); //得到T的具體類 Class<?> clazz = (Class<?>) actualTypeArguments[0]; return clazz; } @Override public void delete(T t) { this.getHibernateTemplate().delete(t); } /** * 建立Hql * @param q * @return */ public abstract String createHql(Q q); /** * 動態設置參數 * @param query * @param q */ public void setDynamicParam(Query query,Q q){ //得到查詢對象的列對象 Class<? extends Object> class1 = q.getClass(); //反向解析查詢對象,列出查詢對象的全部屬性 Field[] declaredFields = class1.getDeclaredFields(); Field[] superFields = class1.getSuperclass().getDeclaredFields(); List<Field> list1 = Arrays.asList(declaredFields); List<Field> list2 = Arrays.asList(superFields); //建立一個大的集合,存儲查詢對象的屬性對象和它父類的屬性對象 List<Field> fList = new ArrayList<Field>(); fList.addAll(list1); fList.addAll(list2); //遍歷集合 for(Field f : fList){ //得到屬性的名字 String fieldName = f.getName(); Object val = null; try { f.setAccessible(true); //得到屬性的值 val = f.get(q); } catch (IllegalArgumentException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(val != null){ if(val.getClass() == String.class){ query.setParameter(fieldName, "%"+val+"%"); }else{ query.setParameter(fieldName, val); } } } } }
其餘的Dao的接口只須要繼承抽取的公共Dao接口;其餘的Dao實現類繼承公共Dao接口的實現類便可。spring