zoukankan      html  css  js  c++  java
  • 使用HibernateDaoSupport抽取BaseDao

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

    一、BaseDao接口及实现的代码

        (1)BaseDao接口的代码
    package com.tax.core.dao;
    import java.io.Serializable; 
    import java.util.List;
    
    /**
     * BaseDao
     * @author ZENG.XIAO.YAN
     * @date 2017年6月29日 上午10:36:57
     * @version v1.0
     */
    public interface BaseDao<T> {
    
    	/**
    	 * 新增
    	 * @param entity
    	 */
    	public void save(T entity);
    
    	/**
    	 * 更新
    	 * @param entity
    	 */
    	public void update(T entity);
    
    	/**
    	 * 根据id删除
    	 * @param id
    	 */
    	public void deleteById(Serializable id);
    
    	
    	/**
    	 * 通过id查找
    	 * @param id
    	 * @return 实体
    	 */
    	public T findById(Serializable id);
    
    	
    	/**
    	 * 查找所有
    	 * @return List集合
    	 */
    	public List<T> findAll();
    }
        
        (2)BaseDaoImpl的代码

    package com.tax.core.dao.impl;
    
    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.util.List;
    import org.hibernate.HibernateException;
    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
    
    import com.tax.core.dao.BaseDao;
    
    /**
     * BaseDaoImpl
     * @author   ZENG.XIAO.YAN
     * @date 	 2017年6月29日 下午12:23:16
     * @version  v1.0
     */
    public abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
    	
    	private Class<T> clazz;
    	
    	// 按照类型自动注入SessionFactory; 在实例化的时候,Spring按照形参的类型自动注入
    	@Autowired
    	public void setMySessionFactory(SessionFactory sessionFactory){
    		setSessionFactory(sessionFactory);
    	}
    	
    	
    	public BaseDaoImpl() {
    		//this表示当前被实例化的对象;如UserDaoImpl
    		ParameterizedType pt = (ParameterizedType)this.getClass().getGenericSuperclass();//BaseDaoImpl<User> 
    		clazz = (Class<T>)pt.getActualTypeArguments()[0];
    	}
    	
    	/**
    	 * 获取session
    	 * @return session
    	 */
    	public Session getCurrentSession(){
    		Session session = null;
    		try {
    			session = getSessionFactory().getCurrentSession();
    		} catch (HibernateException e) {
    			throw new RuntimeException("getCurrentSession error", e);
    			//session = getSessionFactory().openSession();
    		}
    		return session;
    	}
    	
    	@Override
    	public void save(T entity) {
    		getHibernateTemplate().save(entity);
    	}
    	
    	@Override
    	public void update(T entity) {
    		getHibernateTemplate().update(entity);
    	}
    	
    	@Override
    	public void deleteById(Serializable id) {
    		getHibernateTemplate().delete(findById(id));
    	}
    	
    	@Override
    	public T findById(Serializable id) {
    		return getHibernateTemplate().get(clazz, id);
    	}
    	@Override
    	public List<T> findAll() {
    		Session session = getCurrentSession();
    		Query query = session.createQuery("FROM "+ clazz.getSimpleName());
    		return query.list();
    	}
    
    }

        (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就很方便了。
     

     


                               
     


        

    作者:zeng1994
    出处:http://www.cnblogs.com/zeng1994/
    本文版权归作者和博客园共有,欢迎转载!但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接!

  • 相关阅读:
    分析脚本搭建docker环境:python, R
    python 正则
    xargs的用法
    sed 用法
    linux系统时区问题
    docker, docker-compose安装和使用
    订单相关
    python开发接口文档
    mysql中的乐观锁,库存相关的简单实现
    mysql中的锁
  • 原文地址:https://www.cnblogs.com/zeng1994/p/7397573.html
Copyright © 2011-2022 走看看