MyBatis中SqlSession创建过程详解

1、SqlSession接口介绍

SqlSession是MyBatis的主要Java接口,通过这个接口可以执行命令、获取mappers、进行事务管理。

接口的主要方法有:

getMapper(Class): T 规定了获取mapper的方法。

实现类:

2、SqlSessionFactory

SqlSessionFactory接口创建SqlSession,SqlSessionFactory 有一个唯一的必要属性:用于 JDBC 的 DataSource。这可以是任意的 DataSource 对象,它的配置方法和其它 Spring 数据库连接是一样的。

在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的。而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。

示例代码如下:

1
2
3
4
5
6
7
8
9
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean.getObject();
}
}

SqlSessionFactoryBean实现了Spring的FactoryBean接口。这意味着由Spring最终创建的bean并不是SqlSessionFactoryBean本身,而是工厂类(SqlSessionFactoryBean)的getObject()方法的返回结果。

3、追踪mapper的创建过程

通过MapperFactoryBean创建mapper的bean对象

在容器注入MapperSessionFactoryBean

xml方式:

1
2
3
4
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

注解方式:

1
2
3
4
5
6
7
@Bean
public MapperFactoryBean mapperFactoryBean() throws Exception{
MapperFactoryBean mapperFactoryBean = new MapperFactoryBean(PersonMapper.class);
SqlSessionFactory sqlSessionFactory = SqlSessionFactory();
mapperFactoryBean.setSqlSessionFactory(sqlSessionFactory);
return mapperFactoryBean;
}

获取mapper

1
2
3
4
@Bean
public UserMapper userMapper{
return (UserMapper)mapperFactoryBean.getObect();
}

源码解析

MapperFactoryBean类:

继承自SqlSessionDaoSupport

通过构造器将UserMapper接口的类型赋给mapperInterface属性

getObject()方法得到UserMapper接口的代理对象

getSqlSession()方法是父类SqlSessionDaoSupport的方法

由上可知,MapperFactoryBean.getObject()方法的返回值等同于

new SqlSessionTemplate(sqlSessionFactory).getMapper(mapperInterface)的返回值

注意:SqlSessionTemplate是SqlSession的实现类

SqlSessionTemplate.getMapper(type)方法

Configuration.getMapper(type, sqlSession)方法

MapperRegistry.getMapper(type, sqlSession)方法

MapperProxyFactory.newInstance(sqlSession)方法,Proxy.newProxyInstance()是JDK动态代理的方法

由此可追踪到,mapper是实际上就是通过动态代理创建的代理对象。

3、mapper执行sql方法

MapperProxy.execute(sqlSession, args)方法

上图中的sqlSessionSqlSessionTemplate,SqlSessionTemplate.insert(statement, parameter)方法:

SqlSessionProxy的创建,SqlSessionProxy是SqlSession接口的代理对象:

SqlSessionTemplate.SqlSessionInterceptor.invoke()方法中完成事务事务管理