mybatis基础流程_Mybatis与Spring的集成
对象 | 相关对象 | 作用 |
Configuration |
MapperRegistry TypeAliasRegistry TypeHandlerRegistry |
包含了mybatis的所有配置信息 |
SqlSession |
SqlSessionFactory(new 这个DefaultSqlSessionFactory对象的时候,Configuration是作为参数的) DefaultSqlSession |
一个应用层(用户)可以拿来直接对数据库操作的对象(增删改查) |
Executor |
BaseExecutor SimpleExecutor CachingExecutor ResuseExecutor |
创建SqlSession的时候,同时创建了Executor对象,真正操作数据库增删改查的对象 |
StatementHandler | 封装了JDBC Statement的操作, | |
ParameterHandler | 将用户传输的参数转换为JDBC锁可以识别的参数 | |
ResultSetHandler | 将JDBC返回的结果集ResultSet转换为List集合 | |
MapperProxy | MpperProxyFactory | MaperRegistry中存在着一个map, key为Calss,Value为MapperProxyFactory. 其中MapperProxy实现了InvocationHandler ,采用JDK的动态代理,生成Mpper接口的代理对象. |
MapperStatement | 每个Mapper.xml中的<select|update|delete|insert>标签都会封装成一个MapperStatemnt. 里面会存放sql语句id等信息.其中SqlSource的属性BoundSql中会动态生成sql语句. |
1. 如果想要 mybatis 和 spring的融合,首先需要一个jar.
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.0</version>
</dependency>
2. 接下来就是spring的配置文件, applicationContext.xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <
property name="basePackage" value="com.gupaoedu.crud.dao"/>
</bean>
第二种是配置一个<scan>标签:
<mybatis-spring:scan base-package="com.gupaoedu.crud.dao"/>
上面就是如果我们采用之前的ssm框架,常配置的信息,
1. 接下来我们来看一下引入的SqlSessionFactoryBean.
a .这里可以看到SqlSessionFactoryBean 实现了FactoryBean. 涉及到了 spring中的FactoryBean.
FactoryBean 和 BeanFactory区别 :
BeanFactory 从名字得出 , 这是一个Spring容器,而且是Spring提供的一个顶级API, 里面提供了getBean()方法, 来获取实例对象.
FactoryBean从名字看到 , 这本质上是一个Bean, 是Bean的话,就需要交由spring容器来管理,但是我们直接根据beanName获取到的并不是FactoryBean对象,而是由FactoryBean生成的Bean对象(一般当一个对象的生成比较复杂的时候,会再容器内存储FactoryBean对象,然后getBean()的时候,由FactoryBean来创建) , 想获取FactoryBean本身,需要在beanName前加上 & .
a . 这里调用了 buildSqlSessionFactory()方法, 里面我们看到了之前我们在Mybatis中见到的对象, XmlCongigBuilder 和 Configruarion (因为我们配置中表明了主配置文件的位置,所以这可以拿到主配置文件的输入流)
b . 一般spring和mybatis集成,mybatis.xml这个主配置文件只会存在</configuration>标签,其余都是由spring管理的.所以我们spring的配置文件也配置的所有mapper.xml的位置. 一般都是 mapper/*.xml . 这样新增也不会影响扫描
c . xmlConfigBuilder.parse(), 返回Configuration对象
d . 调用xmlMapperBuilder.parse(),这个步骤我们之前了解过了,它的作用是把接口和对应的MapperProxyFactory 注册到MapperRegistry 中。
e . 最终会得到一个DefaultSqlSessionFactory对象
2 . MapperScannerConfigurer
MapperScannerConfigurer :
ClassPathMapperScanner类 :
a . 这里可以看到spring这里得到的BeanDefinition对象,setBeanClass并不是真正的Class对象(其实这里也得不到Class对象,因为从以前的mybatis源码得知,Mapper的Class对象,应该是JDK动态代理去得到的).
b. 正如上面所说,如果这里一个个Mapper的代理对象都由Spring来生成的话,对spring来说太麻烦,所以,这里就放入了MapperFactoryBean, 我们也比较容易猜出来MapperFactoryBean实现了FactoryBean.
a . 所以其实我们正在在代码中使用的时候,是这个MapperFactoryBean的getObject获取到的代理对象.
服务真正开始启动,使用到Mapper对象的时候 :
我们使用Mapper 的时候,只需要在加了Service 注解的类里面使用@Autowired
注入Mapper接口就好了。
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
public List<Employee> getAll() { return employeeMapper.selectByMap(null); }
}
a . 如果系统启动,开始加载EmployeeService类,需要先准备EmployeeMapper对象, 根据beanName,我们从spring容器拿到BeanDefinition对象,对应的Class为MapperFactoryBean.所以我们拿到的是getObject返回的对象.
a . 走到最后一张截图,其实就是我们熟悉的代码了.拿到了MapperProxyFactory. 接下来就是JDK的动态代理了. (MapperProxy实现了InvocationHandler)