Mybatis笔记二

本文介绍了MyBatis与Spring框架整合的过程和技术细节,包括SqlSessionTemplate的使用、SqlSessionInterceptor的作用、以及如何通过MapperFactoryBean和MapperScannerConfigurer实现mapper接口的自动代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mybatis和spring的整合中用到了sqlsessionTemplate,该类实现了SqlSession接口,同时又有一个SqlSession属性,这个属性是一个SqlSession的代理,最后转而执行的是SqlSessionInterceptor这个类里的invoke方法,没错SqlSessionInterceptor实现了InvocationHandler接口。在执行器使用sqlsession时最终会到这个类里去执行。

public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator)
  {
    Assert.notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
    Assert.notNull(executorType, "Property 'executorType' is required");

    this.sqlSessionFactory = sqlSessionFactory;
    this.executorType = executorType;
    this.exceptionTranslator = exceptionTranslator;
    this.sqlSessionProxy = ((SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor(null)));
  }

 private class SqlSessionInterceptor implements InvocationHandler
  {
    private SqlSessionInterceptor()
    {
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
      SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
      try
      {
        Object result = method.invoke(sqlSession, args);
        if (!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory))
        {
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = ExceptionUtil.unwrapThrowable(t);
        if ((SqlSessionTemplate.this.exceptionTranslator != null) && ((unwrapped instanceof PersistenceException))) {
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
      }
    }
  }

在和spring的整合除了给可以给Dao层注入sqlsessionTemplate来管理sqlsession,省去创建sqlsession和关闭sqlsession的代码工作,也可以通过继承SqlSessionDaoSupport这个抽象类,SqlSessionDaoSupport类主要是对sqlsessionTemplate这个再一次封装而已。他有两个属性sqlSessionFactory和sqlSessionTemplate,由spring通过自动装配选择其一来完成,省去了为每个类注入的sqlsessionTemplate的麻烦。但也有缺点就是单继承的问题。


接下来spring还提供了通过mapper代理的配置,主要是MapperFactoryBean和MapperScannerConfigurer。

MapperFactoryBean这个类是用来生成所有mapper接口类的代理类的。他继承了SqlSessionDaoSupport抽象类,实现了FactoryBean接口。

实现了FactoryBean后,spring在获取该对象时候会调用getObject方法,最后调用sqlsession的getMapper方法,也就是实际获取的就是接口的代理类。也就是我们在业务层注入的mapper接口就是MapperFactoryBean生成的一个代理类。

  public T getObject()
    throws Exception
  {
    return getSqlSession().getMapper(this.mapperInterface);
  }

由于一个mapper接口需要配置一个MapperFactoryBean,多了就比较麻烦从而产生了MapperScannerConfigurer


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值