使用HibernateDaoSupport抽取BaseDao

在开发采用Struts2+Spring+hibernate这三大框架的项目时,我们需要一个抽取一个BaseDao。这个Dao里面CRUD都给封装好,后续的其他Dao直接用它的功能就可以。Spring里面有个HibernateDaoSupport的类,这个类需要给他一个SessionFactory。有了SessionFactory后,他就可以做各种操作;最强大的功能是它可以getHibernateTemplate来获取一个HibernateTemplate。有了HibernateTemplate,就有了各种CRUD方法。废话不多说,下面直接看代码

一、BaseDao接口及实现的代码

(1)BaseDao接口的代码

  1. package com.tax.core.dao;
  2. import java.io.Serializable;
  3. import java.util.List;
  4. /**
  5. * BaseDao
  6. * @author ZENG.XIAO.YAN
  7. * @date 2017年6月29日 上午10:36:57
  8. * @version v1.0
  9. */
  10. public interface BaseDao<T> {
  11. /**
  12. * 新增
  13. * @param entity
  14. */
  15. public void save(T entity);
  16. /**
  17. * 更新
  18. * @param entity
  19. */
  20. public void update(T entity);
  21. /**
  22. * 根据id删除
  23. * @param id
  24. */
  25. public void deleteById(Serializable id);
  26. /**
  27. * 通过id查找
  28. * @param id
  29. * @return 实体
  30. */
  31. public T findById(Serializable id);
  32. /**
  33. * 查找所有
  34. * @return List集合
  35. */
  36. public List<T> findAll();
  37. }

(2)BaseDaoImpl的代码

  1. package com.tax.core.dao.impl;
  2. import java.io.Serializable;
  3. import java.lang.reflect.ParameterizedType;
  4. import java.util.List;
  5. import org.hibernate.HibernateException;
  6. import org.hibernate.Query;
  7. import org.hibernate.Session;
  8. import org.hibernate.SessionFactory;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
  11. import com.tax.core.dao.BaseDao;
  12. /**
  13. * BaseDaoImpl
  14. * @author ZENG.XIAO.YAN
  15. * @date 2017年6月29日 下午12:23:16
  16. * @version v1.0
  17. */
  18. public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
  19. private Class<T> clazz;
  20. // 按照类型自动注入SessionFactory; 在实例化的时候,Spring按照形参的类型自动注入
  21. @Autowired
  22. public void setMySessionFactory(SessionFactory sessionFactory){
  23. setSessionFactory(sessionFactory);
  24. }
  25. public BaseDaoImpl() {
  26. //this表示当前被实例化的对象;如UserDaoImpl
  27. ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();//BaseDaoImpl<User>
  28. clazz = (Class<T>)pt.getActualTypeArguments()[0];
  29. }
  30. /**
  31. * 获取session
  32. * @return session
  33. */
  34. public Session getCurrentSession(){
  35. Session session = null;
  36. this.currentSession();
  37. try {
  38. session = getSessionFactory().getCurrentSession();
  39. } catch (HibernateException e) {
  40. session = getSessionFactory().openSession();
  41. }
  42. return session;
  43. }
  44. @Override
  45. public void save(T entity) {
  46. getHibernateTemplate().save(entity);
  47. }
  48. @Override
  49. public void update(T entity) {
  50. getHibernateTemplate().update(entity);
  51. }
  52. @Override
  53. public void deleteById(Serializable id) {
  54. getHibernateTemplate().delete(findById(id));
  55. }
  56. @Override
  57. public T findById(Serializable id) {
  58. return getHibernateTemplate().get(clazz, id);
  59. }
  60. @Override
  61. public List<T> findAll() {
  62. Session session = getCurrentSession();
  63. Query query = session.createQuery("FROM "+ clazz.getSimpleName());
  64. return query.list();
  65. }
  66. }

(3)对BaseDaoImpl的说明

使用HibernateDaoSupport需要注入SessionFactorytory,这个注入的动作其实可以交给BaseDaoImpl的子类去完成的。

如:StudentImpl继承了BaseDaoImpl。那么在Spring的xml文件按照下面配置即可

但是:我觉得这样很麻烦,而且我Dao层我想直接用注解。我不想在每个Dao里都去写这个注入的动作。

所以就准备在BaseDaoImpl里面去完成这个注入动作。

下面开始了我的探索之路:

方案一: 在BaseDaoImpl里面定义SessionFactory的属性,然后属性用注解把它注入。

最后在构造器里把这个SessionFactory通过set给HibernateDaoSupport。

具体的如下图:

结果:虽然想法没问题,但是后面发现在实例化的时候,这个sessionFactory还没注进来。

在项目启动的是时候就报错了,因为我给别人的SessionFactory个设置为null了;所以失败了。

后面通过百度发现,原来Spring容器管理的类中,这个@Autowired注入是在对象实例化完成之后。

所以对Spring容器对bean的实例化过程的还是需要掌握的,笔者在这块掌握得不好。

参考链接:http://blog.csdn.net/xia744510124/article/details/51273576

方案二: 在BaseDaoImpl中定义一个方法,在方法上加个注解。然后方法中把注解注入的形参(sessionFactory)

通过set给HibernateDaoSupport。

具体如下图:



                            结果: 注入成功,这个注解是根据形参的类型自动注入的。sessionFactory会在Spring实例化这Dao后注入。

参考链接:http://blog.csdn.net/tsingheng/article/details/8847047

通过这个探索,发现了自己对Spring的知识掌握得不够,不知道用注解来注入是在对象实例化之后。

二、使用写好的BaseDao和BaseImpl

(1)Dao接口直接继承BaseDao即可,下面以StudentDao接口为例

(2)Dao的实现类,需要继承BaseDaoImpl,下面以StudentDaoImpl为例

三、结束语

通过抽取这个BaseDao,后续的CRUD就很方便了。

时间: 2024-08-24 21:59:46

使用HibernateDaoSupport抽取BaseDao的相关文章

Dao层抽取BaseDao

结构图 BaseDao.java import java.io.Serializable; import java.util.List; import org.hibernate.criterion.DetachedCriteria; public interface BaseDao<T> { //增 void save(T t); //删 void delete(T t); //删 void delete(Serializable id); //改 void update(T t); //查

BaseDao的抽取

在ssh整合开发中,会创建多个不同的dao层对数据库里的数据进行crud操作,其实每个里面用到的方法几乎都一样,只是传递的参数类型不同.我们可以抽取出一个BaseDao类.由于开发中的高内聚低耦合的思想,所以定义为一个接口,再创建实现类继承即可.在接口上定义传递类型的泛型,通过反射技术及Class类中的方法获取. package cn.itcast.util; import java.lang.reflect.ParameterizedType; import java.lang.reflect

JavaEE笔记——BaseDao的使用

在Hibernate框架中使用BaseDao主要的作用是减少冗余代码,在对Dao的操作中CRUD可以说是最普通最常见的操作了,基本上面对不同的数据表都会有类似的CRUD操作,BaseDao的思想就是把这些冗余的操作抽取出来,所以不需要在spring框架的applicationContext.xml中注册,这可能是与其他Dao不同之处.作为一个抽象出来的类,使用这个BaseDao可以使我们的代码更优雅 第一步:和普通Dao一样,先创建个接口 接口中实现的方法有add(添加),update(更新),

JAVAEE——SSH项目实战02:客户列表和BaseDao封装

作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7129152.html 该项目在SSH三大框架整合基础上进行开发:http://www.cnblogs.com/xieyupeng/p/7108141.html 一.客户列表 1.分析 2.书写步骤 (1)封装PageBean public class PageBean { //当前页数 private Integer currentPage; //总记录数 private Intege

006 代码抽取 - bos

一.基于Hibernate的Dao层代码的抽取 1.定义BaseDao接口,其他Dao接口继承该接口 2.在Dao接口定定义基本的增删改查和分页有关的方法 public interface BaseDao<T> { /** * 保存实体 * @param entity */ void save(T entity); /** * 删除实体 * @param entity */ void delete(T entity); /** * 根据实体Id删除实体 * @param id */ void

BaseDao设计示例

本文基于搭建的ssh框架 Dao层有许多重复的简单的增删改查,可以抽取出来,减少冗余代码.分享一下自己的实现案例.有许多深度好文,这里直接上代码. 只是抽取了出来,别的都不用改. Dao层: package cn.itcast.dao; import java.io.Serializable; import java.util.List; import org.hibernate.criterion.DetachedCriteria; public interface BaseDao<T> {

java web项目DAO层通用接口BaseDao与实现类BaseDaoImpl

在spring+hibernate的web项目中,处理数据层通常会使用Spring框架提供的HibernateTemplate类提供的方法.通常的用法是每一个实体类对应的去写DAO层的接口和实现类.每个实现类中都写hibernateTemp.save(entity).hibernateTemp.update(entity).hibernateTemp.get(id)...这样写固然没错,但存在着大量的重复代码.所以懒惰的程序员烦了,他们要写一个通用的实现类来解决这个问题,让DAO层解放出来.如果

利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)

想利用泛型抽取BaseDao层,简化操作时出现问题: @Transactional这个注解是可以继承的,于是就想写在抽取的BaseDao层上,让实现的类可以不用写@Transactional,就可开启事务. 问题描述: 由于偷懒,没给BaseDao抽接口,代码如下: package com.liang.ssh2.base; import java.lang.reflect.ParameterizedType; import java.util.Collections; import java.u

(六)编写基类BaseDao

DAO基类中配备增删改查的操作. 1 public interface BaseDao<T> { 2 //新增 3 public void save(T entity); 4 //更新 5 public void update(T entity); 6 //根据id删除 7 public void delete(Serializable id); 8 //根据id查找 9 public T findObjectById(Serializable id); 10 //查找列表 11 public