对每个实体的增删改查都有相同的方法,可以抽取到一个顶层接口,让实体Dao接口继承。
public interface BaseDao<T> {
/**
* 保存实体
* @param entity
*/
void save(T entity);
/**
* 删除实体
* @param id
*/
void delete(Long id);
/**
* 更新实体
* @param entity
*/
void update(T entity);
/**
* 按id查询
* @param id
* @return
*/
T getById(Long id);
/**
* 按id查询
* @param ids
* @return
*/
List<T> getByIds(Long[] ids);
/**
* 查询所有
* @return
*/
List<T> findAll();
}
接口实现类
public abstract class BaseDaoImpl<T> implements BaseDao<T> {
@Resource
private SessionFactory sessionFactory;
private Class<T> clazz;
public DaoSupportImpl() {
// 使用反射技术得到T的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类类型
this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型
}
/**
* 获取当前可用的Session
*/
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
public void save(T entity) {
getSession().save(entity);
}
public void update(T entity) {
getSession().update(entity);
}
public void delete(Long id) {
Object obj = getById(id);
if (obj != null) {
getSession().delete(obj);
}
}
public T getById(Long id) {
if (id == null) {
return null;
} else {
return (T) getSession().get(clazz, id);
}
}
public List<T> getByIds(Long[] ids) {
if (ids == null || ids.length == 0) {
return Collections.EMPTY_LIST;
} else {
return getSession().createQuery(//
"FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")//
.setParameterList("ids", ids)//
.list();
}
}
public List<T> findAll() {
return getSession().createQuery(//
"FROM " + clazz.getSimpleName())//
.list();
}
}
假如有一User类,对应有UserDao 和 UserDaoImpl,可以这样实现
public interface UserDao extends BaseDao<User> {
// 该接口继承BaseDao接口,还可以写自己的接口
}
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {
//
}
由于UserDaoImpl 继承了BaseDaoImpl,所有有公共方法。因实现了UserDao 接口,可以实现UserDao 接口中的方法。