在hibernate中实现泛型DAO时,最大的一个难点就是获得泛型类型的class对象。
public class GenericHibernateDao<T extends Serializable, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T,PK>{
private Class<T> entityClass;
// 构造方法,根据实例类自动获取实体类类型
public GenericHibernateDao() {
this.entityClass = null;
Class c = getClass();
Type t = c.getGenericSuperclass();
if (t instanceof ParameterizedType) {
Type[] p = ((ParameterizedType) t).getActualTypeArguments();
this.entityClass = (Class<T>) p[0];
}
}
}
这是泛型DAO的泛型实现类。我们的DAO类可以继承自这个类。例如class UserDao extends GenericHibernateDao<UserBean , int>。当我们去实例化UserDao的时候,就会去自动调用GenericHibernateDao中的构造方法(子类会首先调用父类的构造方法)。下面我们来分析父类的构造方法,看看他是怎么获得UserBean类型的。
Class c = getClass();这一句。表面上看是获得GenericHibernateDao类的实例,但是应该是子类的实例。
c也就代表了子类的class对象。
Type t = c.getGenericSuperclass()。得到父类的类型。
t instanceof ParameterizedType。检查父类是否是泛型(即参数化类)
Type[] p = ((ParameterizedType) t).getActualTypeArguments()。如果是泛型,那么得到所有的泛型参数。
this.entityClass = (Class<T>) p[0]。得到第一个参数类型。也就是UserBean了。