Hibernate 的应用7 —— 与 Spring 的整合

Spring 的 DAO 支持

Spring 提供许多工具类用于对 DAO 实现简化开发步骤

Spring 提供了一致的异常抽象,将原有的 Checked 异常转换包装为 Runtime 异常,因而,编码时无序捕获各种技术中特定的异常

  • HibernateTemplate

    public class PersonDaoImpl implements PersonDao {
    
        private HibernateTemplate ht = null;
    
        @Resource(name="sessionFactory")
        protected SessionFactory sessionFactory;
        
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
        
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        } 
        
        private HibernateTemplate getHibernateTemplate() {
            if (ht == null) {
                ht = new HibernateTemplate(sessionFactory);
            }
            return ht;
        }
        
        // HibernateTemplate 的使用类似于 Session + Query
        public Person get(Integer id) {
            return getHibernateTemplate().get(Person.class, id);
        }
    }
    

    缺点:灵活性不足,不能用 Hibernate API 进行持久化访问

  • HibernateCallback 接口

    • HibernateTemplate 的 .execute(HibernateCallback action).executeFind(HibernateCallback action) 方法接收一个 HibernateCallback 接口的实现
    • HibernateCallback 接口包含 doInHibernate(Session session) 方法
    • 两者结合可解决灵活应用 Hibernate API 的问题
    public class PersonDaoImpl implements PersonDao {
    
        private HibernateTemplate ht = null;
    
        @Resource(name="sessionFactory")
        protected SessionFactory sessionFactory;
        
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
        
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        } 
        
        private HibernateTemplate getHibernateTemplate() {
            if (ht == null) {
                ht = new HibernateTemplate(sessionFactory);
            }
            return ht;
        }
        
        public Person get(final Integer id) {
            return getHibernateTemplate().execute(new HibernateCallback() {
                public Object doInHibernate(Session session) throws HibernateException, SQLException {
                    return session.get(Person.class, id);
                }
            });
        }
    }
    
  • HibernateDaoSupport

    • HibernateDaoSupport 的 getHibernateTemplate() 方法返回 HibernateTemplate 对象
    • HibernateDaoSupport 的 setSessionFactory(SessionFactory sessionFactory) 可用于接收 Spring 的依赖注入,从而允许使用 sessionFactory 对象
    • HibernateDaoSupport 的 DAO 实现由 HibernateTemplate 对象完成
    • DAO 类的实现继承 HibernateDaoSupport

Spring 使用声明式事务

  • Spring 使用声明式事务来进行统一的事务管理
  • 只需要在配置文件中增加事务控制片段,业务逻辑组件的方法将会有事务性
  • Spring 的声明式事务支持在不同事务策略之间自由切换

配置 applicationContext.xml 文件



    
    
    
    
    
    
    
    

配置 dataSource 和 sessionFactory

  • 直接在 spring 的配置文件 applicationContext.xml 中配置
    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    
    
    
    
        
        
        
        
            
                org.hibernate.dialect.MySQL5Dialect
                true
                true
                update
            
        
        
        
    
    
  • 引用 Hibernate 的配置文件 hibernate.cfg.xml
    
    
        
        
        
        
    
    

当相同的配置项都存在时,applicationContext.xml 中的优先级高于 hibernate.cfg.xml

配置事务

  • XML 配置

    
    
        
    
    
    
    
        
        
            
            
            
            
            
        
    
    
    
        
        
        
        
    
    
  • Annotation

    
    
        
    
    
    
    
    
    • @Transactional(...)

      属性 说明
      name 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器
      propagation 事务的传播行为,默认值为 REQUIRED
      isolation 事务的隔离度,默认值采用 DEFAULT
      timeout 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务
      read-only 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true
      rollback-for 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔
      no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务

透彻的掌握 Spring 中@transactional 的使用

Spring @Transactional工作原理

Spring @Transactional原理及使用

Hibernate 框架下的通用 DAO 层

BaseDao.java

/**
 * 通用泛型DAO
 */
public interface BaseDao {

    /**
     * 新增一个实例
     * @param entity 要新增的实例 
     */
    public void save(T entity);
    
    /**
     * 根据主键删除一个实例 
     * @param id 主键
     */
    public void delete(int id);
    
    /**
     * 编辑指定实例的详细信息
     * @param entity 实例 
     */
    public void edit(T entity);
    
    /**
     * 根据主键获取对应的实例 
     * @param id 主键值
     * @return 如果查询成功,返回符合条件的实例;如果查询失败,返回null
     */
    public T get(Integer id);
    
    /**
     * 根据主键获取对应的实例 
     * @param id 主键值
     * @return 如果查询成功,返回符合条件的实例;如果查询失败,抛出空指针异常
     */
    public T load(Integer id);
    
    /**
     * 获取所有实体实例列表
     * @return 符合条件的实例列表
     */
    public List findAll();
    
    /**
     * 统计总实体实例的数量
     * @return 总数量
     */
    public int totalCount();
    
    /**
     * 获取分页列表
     * @param pageNo 当前页号
     * @param pageSize 每页要显示的记录数
     * @return 符合分页条件的分页模型实例
     */
    public PageModel findByPager(int pageNo, int pageSize);
    
    /**
     * 根据指定的SQL语句和参数值执行更新数据的操作
     * @param sql SQL语句
     * @param paramValues 参数值数组
     */
    public void update(String sql);
    
    /**
     * 根据指定的SQL语句和参数值执行单个对象的查询操作
     * @param sql SQL语句
     * @param paramValues 参数值
     * @return 符合条件的实体对象
     */
    public T findUnique(String sql);
}

BaseDaoImpl.java

/**
 * 通用DAO接口的实现类
 */
@SuppressWarnings("unchecked")
public class BaseDaoImpl implements BaseDao {

    /**
     * 对应的持久化类
     */
    private Class clazz;
    
    @Resource(name="sessionFactory")
    protected SessionFactory sessionFactory;
    
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    
    public BaseDaoImpl(){
        //通过反射机制获取子类传递过来的实体类的类型信息
        ParameterizedType type=(ParameterizedType)this.getClass().getGenericSuperclass();
        this.clazz=(Class)type.getActualTypeArguments()[0];
    }

    @Override
    public void save(T entity) {
        Session session = sessionFactory.getCurrentSession();
        session.save(entity);
    }

    @Override
    public void delete(int id) {
        Session session = sessionFactory.getCurrentSession();
        session.delete(get(id));
    }

    @Override
    public void edit(T entity) {
        Session session = sessionFactory.getCurrentSession();
        session.merge(entity);
    }

    @Override
    public T get(Integer id) {
        Session session = sessionFactory.getCurrentSession();
        return (T) session.get(clazz, id);
    }

    @Override
    public T load(Integer id) {
        Session session = sessionFactory.getCurrentSession();
        return (T)session.load(clazz, id);
    }

    @Override
    public List findAll() {
        Session session = sessionFactory.getCurrentSession();
        String hql = "select t from "+clazz.getSimpleName()+" t";
        return (List)session.createQuery(hql).list();
    }

    @Override
    public int totalCount() {
        Session session = sessionFactory.getCurrentSession();
        int count = 0;
        String hql = "select count(t) from "+clazz.getSimpleName()+" t";
        Long temp = (Long)session.createQuery(hql).uniqueResult();
        if(temp != null){
            count = temp.intValue();
        }
        return count;
    }

    @Override
    public PageModel findByPager(int pageNo, int pageSize) {
        Session session = sessionFactory.getCurrentSession();
        PageModel pm = new PageModel(pageNo, pageSize);
        String hql = "select t from "+clazz.getSimpleName()+" t";
        int startRow = (pageNo - 1) * pageSize;
        pm.setDatas(session.createQuery(hql).setFirstResult(startRow).setMaxResults(pageSize).list());
        pm.setRecordCount(totalCount());
        return pm;
    }

    @Override
    public void update(String hql) {
        Session session = sessionFactory.getCurrentSession();
        session.createQuery(hql);
    }

    @Override
    public T findUnique(String hql) {
        Session session = sessionFactory.getCurrentSession();
        return (T)session.createQuery(hql).uniqueResult();
    }
}

PageModel.java

/**
 * 分页模型类
 */
public class PageModel {

    //当前页号
    private int pageNo=1;
    //每页显示的记录数
    private int pageSize=10;
    //总记录数
    private int recordCount;
    //总页数
    private int pageCount;
    //存放分页数据的集合
    private List datas;
    
    public PageModel(){
        
    }
    
    public PageModel(int pageNo,int pageSize){
        this.pageNo=pageNo;
        this.pageSize=pageSize;
    }

    public int getPageNo() {
        return pageNo;
    }

    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getRecordCount() {
        return recordCount;
    }

    public void setRecordCount(int recordCount) {
        this.recordCount = recordCount;
    }

    public int getPageCount() {
        if(this.getRecordCount()<=0){
            return 0;
        }else{
            pageCount=(recordCount+pageSize-1)/pageSize;
        }
        return pageCount;
    }

    public void setPageCount(int pageCount) {
        this.pageCount = pageCount;
    }

    public List getDatas() {
        return datas;
    }

    public void setDatas(List datas) {
        this.datas = datas;
    }
}

你可能感兴趣的:(Hibernate 的应用7 —— 与 Spring 的整合)