1. 抽取增、删、改
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
public void save(T t) {
this.getHibernateTemplate().save(t);
}
public void update(T t) {
this.getHibernateTemplate().update(t);
}
public void delete(T t) {
this.getHibernateTemplate().delete(t);
}
}
2. 抽取查询
2.1 方式一:在实现类的构造方法中传入一个class
实现思路:在父类中提供一个有参数的构造函数,参数为Class类型,在子类中继承父类,提供构造函数,在子类的构造函数中,通过super关键字,调用父类的有参构造器
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
private Class clazz;
public BaseDaoImpl(Class clazz){
this.clazz = clazz;
}
// 通过ID实现查询
public T findById(Serializable id){
return (T) this.getHibernateTemplate().get(clazz, id);
}
}
在实现类中
public LinkManDaoImpl(){
super(LinkMan.class);
}
2.2 方式二:通过泛型的反射来抽取查询
通过构造函数方式可以实现查询的抽取,但是实现起来会麻烦点,我们需要Dao中都显示的提供构造函数,现在我希望将Dao中的构造方法去掉,将父类的通用Dao中提供无参数的构造即可,这时候,就需要在无参数的构造函数中获取具体类型的class,我们通过泛型的反射来实现这个需求。
2.2.1 泛型的相关术语
泛型:通用的类型
<>:念做 type of
List<E>:E称之为类型参数变量
ArrayList<Integer> :Integer称之为实际类型参数
ArrayList<Integer>:ArrayList<Integer>称之为参数化类型ParameterizedType
所以,我们的需求就可以概括为:在父类的构造函数中获得子类继承父类上的参数化类型中的实际类型
2.2.2 通过反射,获取实际类型
public BaseDaoImpl<T>{
// 反射:第一步获取class
Class clazz = this.getClass(); // this指正在被调用的那个类,即继承BaseDaoImpl的类,比方说CustomerDaoImpl
// 获取子类的父类的参数化类型CustomerDaoImpl extends BaseDapImpl<Customer>
Type type = clazz.getGenericSuperclass();
// 将Type类型强转为参数化类型
ParameterizedType pType = (ParameterizedType)type;
// 获取实际类型参数
Type[] actualTypes = pType.getActualTypeArguments();
// 这里只需要获取1个就可以了 ,因为Type接口的实现类是Class,所以,可以直接强转
this.clazz = (Class) actualTypes[0];
}
这样,在具体的实现类中,只需要写其特有的方法即可,一些通用的都可以抽取到BaseDaoImpl中去了