基于Spring4和Hibernate4的通用泛型DAO实现


通用DAO实现的目的
是为了将纷繁重复的数据库操作统一放到一个公共类中统一处理,将精力从重复的劳动中抽离
1)


通用DAO接口设计

  • 只展示CRUD操作2)
public interface GenericDao<T extends BaseEntity, PK extends Serializable> {
 
  public PK save(T t);
 
  public void delete(T t);
 
  public void update(T t);
 
  public T findUnique(Class<T> entityClass, PK paramSerializable);
 
}

通用DAO实现

public class GenericDaoImpl<T extends BaseEntity, PK extends Serializable> implements GenericDao<T, PK> {
 
  @Autowired
  private SessionFactory sessionFactory;
 
  private Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
  }
 
  @Override
  public PK save(T t) {
    return (PK) getCurrentSession().save(t);
  }
 
  @Override
  public void delete(T t) {
    getCurrentSession().delete(t);
  }
 
  @Override
  public void update(T t) {
    getCurrentSession().update(t);
  }
 
  @Override
  public T findUnique(Class<T> entityClass, PK id) {
    return (T) getCurrentSession().get(entityClass, id);
  }
 
}

具体使用配置

    由于Java中的泛型信息只在编译器有效,在运行期被擦除,也就是说所有泛型参数类型信息在编译后都会被清除掉。所以直接在
    Service中使用GenericDao<Entity, String>类似的自动注入字段是会引发异常的。因此只有交给Spring容器去管理泛型信息,
    我们知道Spring的依赖注入,IOC是在运行期实现的,单单添加自动注入的注解肯定是不行的。基于以上的原因,我们需要在使用
    时,手动的配置泛型信息,让Spring容器解析出泛型信息,完成自动注入泛型DAO。
  • 配置信息示例
@Configuration
public class QrcodeDaoConfiguration {
  @Bean
  public GenericDao<QrcodeInfo, String> createQrcodeInfoDao() {
    return new GenericDaoImpl<>();
  }
 
  @Bean
  public GenericDao<QrcodeType, String> createQrcodeTypeDao() {
    return new GenericDaoImpl<>();
  }
 
  @Bean
  public GenericDao<MatchCode, String> createMatchCodeDao() {
    return new GenericDaoImpl<>();
  }
}
  • 使用示例
  @Autowired
  private GenericDao<QrcodeType, String> typeDao;
    使用时申明需要自动注入的泛型DAO,Spring从配置信息中匹配符合的泛型Bean结果,实现自动装配。

总结和思考

    通过以上的配置,就能实现基本的通用泛型DAO结构,已经可以替代以前的DAO层结构。但是,Java中的泛型是没有办法从泛型中获取到
    字节码信息的,所以在和Hibernate结合使用时,很多时候需要传入类型信息。这样的话,我们是否应该将以上的泛型DAO实现转换为一
    个非泛型无配置文件的通用DAO结构设计更好呢。

Copyright © 2014 北京微朴信息技术有限责任公司

1) 目前还处于逐步完善的阶段
2) 在实体类的层次结构中本应该以BaseEntity为顶层实体抽象,基于项目中使用到的未基于BaseEntity的实现,已经将BaseEntity调整为Object