一、作用
减少Dao代码的书写量
二、原理
(1)将增删查改方法抽取到BaseDao接口
(2)为BaseDao接口完成通用实现类
(3)以后书写Dao时,就可以不用写这些通用的方法,只要继承BaseDaoImpl类就可以了
三、代码书写
1、BaseDao:
import java.io.Serializable;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
public interface BaseDao <T>{
//增或更新
void saveOrUpdate(T t);
//删
void delete(T t);
//删
void delete(Serializable id);
//查 根据id查询
T getById(Serializable id);
//查 符合条件的总记录数
Integer getTotalCount(DetachedCriteria dCriteria);
//查 查询分页列表数据
List<T> getPageList(DetachedCriteria dCriteria, Integer start, Integer pageSize);
}
注意:BaseDao中变量id的类型是Serializable,因为不同JavaBean的id可能是不同类型(string、Integer),所有此处使用Serializable接口,八大基础类型和String都实现了该接口。
hibernate的get、load方法中第二个参数就是serializable。
2、BaseDaoImplement:
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import club.ityuchao.dao.BaseDao;
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;//用于接受运行时期的泛型
public BaseDaoImpl() {
//Type接口是反射类型的最顶层接口,class也是该接口的实现类,就像所有对象顶层对象Object一样
ParameterizedType ptClass = (ParameterizedType)this.getClass().getGenericSuperclass();//获得带有泛型类型的父类
clazz = (Class) ptClass.getActualTypeArguments()[0];//该方法获得的是一个泛型类型的数组
}
@Override
public void saveOrUpdate(T t) {
getHibernateTemplate().saveOrUpdate(t);
}
@Override
public void delete(T t) {
getHibernateTemplate().delete(t);
}
@Override
public void delete(Serializable id) {
T t = this.getById(id);
this.delete(t);
}
@Override
public T getById(Serializable id) {
return (T)getHibernateTemplate().get(clazz, id);
}
@Override
public Integer getTotalCount(DetachedCriteria dCriteria) {
//设置聚合函数
dCriteria.setProjection(Projections.rowCount());
List<Long> list = (List<Long>) getHibernateTemplate().findByCriteria(dCriteria);
//清除聚合函数
dCriteria.setProjection(null);
if(list != null && list.size() > 0) {
return list.get(0).intValue();
}
return null;
}
@Override
public List<T> getPageList(DetachedCriteria dCriteria, Integer start, Integer pageSize) {
List<T> list = (List<T>) getHibernateTemplate().findByCriteria(dCriteria, start, pageSize);
return list;
}
}
注意:由于该类中有的方法必须获得泛型类型,所有此处有获得运行时期的泛型类型的方法。
Type接口是反射类型的最顶层接口,class也是该接口的实现类
其他Dao书写,此处以UserDao为例:
3、UserDao:
import club.ityuchao.domain.User;
public interface UserDao extends BaseDao<User> {
//此处省略通用增删查改方法
//根据登录名获得
User getBuyUserCode(String userCode);
}
4、UserDaoImpl:
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import club.ityuchao.dao.UserDao;
import club.ityuchao.domain.User;
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {
//此处省略通用增删查改方法
public User getBuyUserCode(final String codeName) {
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
dc.add(Restrictions.eq("codeName", codeName));
List<User> list = (List<User>) getHibernateTemplate().findByCriteria(dc);
if(list != null && list.size() > 0) {
return list.get(0);
}else {
return null;
}
}
}
如此抽取公共的方法之后,就可以直接调用UserDao的增删查改方法了