背景
1.每个Impl接口都要写get,delete,save,update,list,query的方法
2.每个DAO类都要去实现impl的方法.
结果:造成大量接口和类的代码重复—>违背dry原则
泛型DAO接口
1.声明T需要继承于BaseDomain.
2.声明6个接口方法
public interface IgenericDAO<T extends BaseDomain> {
public void delete(T o);
public T get(Long id);
public void save(T o);
public void update(T o);
public List<T> list();
public Page<List<T>> getPage(IQuery q);
}
此后的所有DAO接口的写法,只需要继承泛型DAO接口
public interface IEmployeeDAO extends IgenericDAO<Employee>{}
泛型DAO实现类
1.实现类中需要将泛型T实体化
- TClass:传入的类的Class对象
- TSimpleName:传入的类的简单名
2 . 实现类要继承于IgenericDAO<T>
@SuppressWarnings("unchecked")
public abstract class genericDAOImpl<T extends BaseDomain> implements IgenericDAO<T>{
//将泛型T具体化,通过构造器
private Class<?> TClass;
private String TSimpleName;
public genericDAOImpl() {
this.TClass = (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
this.TSimpleName=TClass.getSimpleName();
}
//Spring注入session工厂
@Autowired
private SessionFactory sessionFactory;
//delete
public void delete(T o) {
Session session = sessionFactory.getCurrentSession();
session.delete(o);
}
//get 需要用到TClass
public T get(Long id) {
Session session = sessionFactory.getCurrentSession();
return (T)session.get(TClass, id);
}
//save
public void save(T o) {
Session session = sessionFactory.getCurrentSession();
session.save(o);
}
//update
public void update(T o) {
Session session = sessionFactory.getCurrentSession();
session.update(o);
}
//list 需要用到TSimpleName
public List<T> list() {
Session session = sessionFactory.getCurrentSession();
String HQL="select o from "+this.TSimpleName+" o "+" order by o.id asc";
List<T> list = session.createQuery(HQL).list();
return list;
}
//高级查询 只要将两个HQL主体改一下类名, ps 以后的XXXObjct要以o为对象了
public Page<List<T>> query(IQuery q) {
Session session = sessionFactory.getCurrentSession();
//获取totalCount
String countHQL ="select count(o) from "+this.TSimpleName+" o "+ q.getCountHQL();
Query countQuery = session.createQuery(countHQL);
this.setParamter(countQuery, q.getCountParameters());
int totalCount= ((Long)countQuery.list().get(0)).intValue();
//获取currentPage
Integer currentPage = q.getCurrentPage();
//获取pageSize
Integer pageSize = q.getPageSize();
//获取list
String listHQL="select o from "+this.TSimpleName+" o "+q.getListHQL();
Query listQuery = session.createQuery(listHQL);
this.setParamter(listQuery, q.getListParameters());
List<T> list = listQuery.setFirstResult((currentPage-1)*pageSize).setProperties(pageSize).list();
return new Page<List<T>>(totalCount, currentPage, pageSize, list);
}
//循环设置参数
private void setParamter(Query query,List<Object> list) {
for (int i=0;i<list.size();i++) {
query.setParameter(i, list.get(i));
}
}
}
此后的DAO实现类只需要
1. **实现**DAO接口
2. 继承泛型DAO实现类
3. 构造器中声明调用父类构造器(将泛型T具体化)
public class EmployeeDAOImpl extends genericDAOImpl<Employee> implements IEmployeeDAO{
public EmployeeDAOImpl() {
super();
}
}