设计通用持久层的好处
多个类相同的操作数据库方法可以用一个类来解决,如:基本的增删改查等操作。
1.通用持久层如何设计,基于泛型和反射
1.1通用持久层,意味着多个实体类都可以用的持久层,那么我们只能用泛型来定义数据类型
1.2泛型来定义数据类型,我们需要通过传递过来的泛型创建出我们正真的实体对象,这时反射就出场了。
2.案例
(1) IBaseDao<T>就是一个通用的持久层,BaseDaoImpl<T>就是一个通用持久层的实现。
(2) IUserDao就是专门针对UserDaoImpl操作的接口
(3) UserDaoImpl继承BaseDaoImpl类和实现IUserDao接口的好处是,都是IBaseDao<T>的子类,在IUserDao里面基本的增删改查,已经在BaseDaoImpl里面有实现,简化了开发过程中代码的书写。
通用接口的编码案例:
1 /** 2 * 抽取持久层通用方法 3 * @param <T> 4 */ 5 public interface IBaseDao<T> { 6 public void save(T entity); 7 public void delete(T entity); 8 public void update(T entity); 9 public T findById(Serializable id); 10 public List<T> findAll(); 11 } 12 通用实现: 13 /** 14 * 持久层通用实现 15 * 16 */ 17 public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T>{ 18 //实体类型 19 private Class<T> entityClass; 20 //使用注解方式进行依赖注入 21 @Resource 22 public void setMySessionFactory(SessionFactory sessionFactory){ 23 super.setSessionFactory(sessionFactory); 24 } 25 26 /** 27 * 在构造方法中动态获得操作的实体类型 28 */ 29 public BaseDaoImpl() { 30 //获得父类(BaseDaoImpl<T>)类型,需要好好理解 31 ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass(); 32 //获得父类上的泛型数组,这个是在子类中传递进来的。 33 Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments(); 34 entityClass = (Class<T>) actualTypeArguments[0];//获取第一个数据类型 35 } 36 37 public void save(T entity) { 38 this.getHibernateTemplate().save(entity); 39 } 40 41 public void delete(T entity) { 42 this.getHibernateTemplate().delete(entity); 43 } 44 45 public void update(T entity) { 46 this.getHibernateTemplate().update(entity); 47 } 48 49 public T findById(Serializable id) { 50 return this.getHibernateTemplate().get(entityClass, id); 51 } 52 53 public List<T> findAll() {//FROM User 54 String hql = "FROM " + entityClass.getSimpleName(); 55 return this.getHibernateTemplate().find(hql); 56 } 57 }