zoukankan      html  css  js  c++  java
  • mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题

    我们公司的项目使用spring+mybatis组合。所以就必须得使用mybatis-spring了。所以此处就昨日mybatis-spring从1.1升级到1.2所带来的dao层级的编写问题,做了一个总结。

    我们可以先来看看mybatis-spring框架的1.1.1版本中关于SqlSessionDaoSupport的代码吧:

    package org.mybatis.spring.support;
    
    import static org.springframework.util.Assert.*;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.support.DaoSupport;
    
    /**
     * Convenient super class for MyBatis SqlSession data access objects.
     * It gives you access to the template which can then be used to execute SQL methods.
     * <p>
     * This class needs a SqlSessionTemplate or a SqlSessionFactory.
     * If both are set the SqlSessionFactory will be ignored.
     *
     * @see #setSqlSessionFactory
     * @see #setSqlSessionTemplate
     * @see SqlSessionTemplate
     * @version $Id: SqlSessionDaoSupport.java 4885 2012-03-12 09:58:54Z simone.tripodi $
     */
    public abstract class SqlSessionDaoSupport extends DaoSupport {
    
      private SqlSession sqlSession;
    
      private boolean externalSqlSession;
    
      @Autowired(required = false)
      public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        if (!this.externalSqlSession) {
          this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
        }
      }
    
      @Autowired(required = false)
      public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSession = sqlSessionTemplate;
        this.externalSqlSession = true;
      }
    
      /**
       * Users should use this method to get a SqlSession to call its statement methods
       * This is SqlSession is managed by spring. Users should not commit/rollback/close it
       * because it will be automatically done.
       *
       * @return Spring managed thread safe SqlSession
       */
      public final SqlSession getSqlSession() {
        return this.sqlSession;
      }
    
      /**
       * {@inheritDoc}
       */
      protected void checkDaoConfig() {
        notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
      }
    
    }
    

      从上面的源码可以看出:在方法setSqlSessionFactory和setSqlSessionTemplate方法上面都标注有:“@Autowired(required = false)”这样的注解。

    所以我们在编写dao层级代码的时候只需要dao直接继承SqlSessionDaoSupport,并标注注解@Repository,然后就可以使用类似的getSqlSession().selectList("User.selectUsers");这样的方法来使用它了,而且在spring的配置文件中的配置也比较少:

     <tx:annotation-driven transaction-manager="txManager"
                              proxy-target-class="true"/>
    
        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>
    
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
        </bean>
    

      

      但是升级到1.2之后,我们看看SqlSessionDaoSupport的源代码:

    public abstract class SqlSessionDaoSupport extends DaoSupport {
    
      private SqlSession sqlSession;
    
      private boolean externalSqlSession;
    
      public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
        if (!this.externalSqlSession) {
          this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
        }
      }
    
      public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSession = sqlSessionTemplate;
        this.externalSqlSession = true;
      }
    
      /**
       * Users should use this method to get a SqlSession to call its statement methods
       * This is SqlSession is managed by spring. Users should not commit/rollback/close it
       * because it will be automatically done.
       *
       * @return Spring managed thread safe SqlSession
       */
      public SqlSession getSqlSession() {
        return this.sqlSession;
      }
    
      /**
       * {@inheritDoc}
       */
      protected void checkDaoConfig() {
        notNull(this.sqlSession, "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required");
      }
    
    }
    

      

      从上面的源码可以看出:在方法setSqlSessionFactory和setSqlSessionTemplate方法上面现在都没有标注有:“@Autowired(required = false)”这样的注解。

    如果一些系统直接从mybatis-spring1.1.1升级到1.2版本的时候,就会出现问题。

    在1.2版本下面有几种方式来使用:

    第一种,基于注解:

    @Repository
    public class UserDao extends SqlSessionDaoSupport{
        public List<User> userList() {
            return getSqlSession().selectList("User.selectUsers");
        }
    
        @Override
        @Autowired
        public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
            super.setSqlSessionFactory(sqlSessionFactory);
        }
    }
    

      

      我们自己重写set方法就可以了。在这种情况下spring的配置文件不需要修改。这个实例是随意写的,如果你的工程中dao类很多(绝大多数情况都是),这样你就可以编写一个BaseDao,然后在这个BaseDao中重写这个方法,其他的dao只需要继承这个BaseDao就可以了。

    第二章基于xml文件配置:

    public class UserDao extends SqlSessionDaoSupport {
        public List<User> userList() {
            return getSqlSession().selectList("User.selectUsers");
        }
    }
    

      

      但是需要在spring的配置文件中增加这个UserDao的配置:

        <bean id="userDao" class="com.xxx.paginator.dao.UserDao">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
    

      

      第一种基于注解的配置,好处是不需要编写xml,但是这种比较容易侵入业务逻辑。

         第二种基于xml配置,好处是不侵入业务逻辑,但是当dao的数量很多的时候,需要在xml中配置好多。

         所以最后具体选择哪种,大家可以结合自己的情况。

  • 相关阅读:
    2015.2.27 UltraEdit中显示XML结构
    2015.1.31 DataGridView自动滚动到某行
    2015.1.15 利用函数实现将一行记录拆分成多行记录 (多年想要的效果)
    2015.1.15 利用Oracle函数返回表结果 重大技术进步!
    2015.1.15 利用Oracle函数插入表结构 Bulk collect into 不用循环,简洁高效
    2015.1.8 Left join 左连接
    2015.1.10 解决DataGridView SelectionChanged事件自动触发问题
    delphi 遍历窗口
    delphi 访问 protected 属性 哈哈
    clientdataset 读取excel 如果excel 文件不存在的时候 相应的gird 会不显示数据, 鼠标掠过 gird 格子 才会显示数据。 这是一个bug 哈哈
  • 原文地址:https://www.cnblogs.com/rollenholt/p/3358650.html
Copyright © 2011-2022 走看看