目录

  • 为什么 `MyBatis` 要和 `Spring` 整合
  • `Spring` 整合 `MyBatis`
    • `Maven` 依赖
    • 创建 `Spring` 配置文件
    • 创建 `MyBatis` 配置文件
    • 创建 `Mapper` 映射文件
    • 创建测试类
  • `SqlSessionFactory` 对象的产生
    • `SqlSessionFactoryBean` 源码
      • `FactoryBean` 接口
      • `InitializingBean` 接口
      • `getObject()` 和 `afterPropertiesSet()` 的实现
  • 总结

为什么 MyBatis 要和 Spring 整合

  • Spring 会帮助我们管理 bean:省去我们对 SqlSessionFactory、SqlSession、Mapper 映射器这些核心对象(bean)的创建,不需要我们手工去创建了,Spring 会通过 IOC 容器来帮我们管理这些对象
  • Spring 使用 xxxTemplate 封装了方法:Spring 整合 MyBatis,它为我们提供了一个 xxxTemplate 方法,方便我们去调用

Spring 整合 MyBatis

Maven 依赖

<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.2</version>
</dependency>

创建 Spring 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/><property name="password" value="123abc"/></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="configLocation" value="classpath:/resource/cfg.xml"/><property name="dataSource" ref="dataSource"/></bean><bean id="mapperFactoryBean" class="org.mybatis.spring.mapper.MapperFactoryBean"><property name="mapperInterface" value="net.itaem.dao.PersonDao"/><property name="sqlSessionFactory" ref="sqlSessionFactory"/></bean>
</beans>

创建 MyBatis 配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>  <!-- mapping 文件路径配置 -->  <mappers>  <mapper resource="resource/PersonMapper.xml" />  </mappers>
</configuration>

创建 Mapper 映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="net.itaem.dao.PersonDao" ><resultMap id="resultMap" type="net.itaem.po.Person" ><result column="id" property="id" jdbcType="CHAR" /><result column="name" property="name" jdbcType="CHAR" /></resultMap><!--添加--> <insert id="save"  parameterType="net.itaem.po.Person">insert into person(id,name) value(#{id,jdbcType=CHAR},#{name,jdbcType=CHAR})</insert><!--查询--><select id="query"  resultMap="resultMap">select * from person</select><!--删除--><delete id="delete" parameterType="java.lang.String">delete from person  where id=#{id,jdbcType=CHAR}</delete>
</mapper>

创建测试类

public class SpringTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("resource/applicationContext.xml");PersonDao personDao = (PersonDao) context.getBean("personDao");Person person = new Person("12","Fighter168");personDao.save(person);}
}

通过上面的比较,我们发现,在 Spring 中使用 MyBatis 是相当方便的,不需要我们去管理 SqlSessionFactory 以及 SqlSession 的对象(bean

SqlSessionFactory 对象的产生

我们已经了解到,MyBatis 的使用离不开 SqlSessionFactory、SqlSession、Mapper 这三大对象。这三大对象是如何被创建的呢?我们先看 SqlSessionFactory 对象的产生

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="configLocation" value="classpath:/resource/cfg.xml"/><property name="dataSource" ref="dataSource"/>
</bean>

我们已经在 applicationContext.xml 中配置了 sqlSessionFactoryBean,通过名称我们便可以大概了解到该 bean 就是用来为我们创建 sqlSessionFactory 对象的类

SqlSessionFactoryBean 源码

mybatis-spring-1.3.2.jar 包中找到 SqlSessionFactoryBean 类,源码如下

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {private Resource configLocation;private Configuration configuration;private Resource[] mapperLocations;private DataSource dataSource;private TransactionFactory transactionFactory;private Properties configurationProperties;private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();private SqlSessionFactory sqlSessionFactory;private boolean failFast;private Interceptor[] plugins;private TypeHandler<?>[] typeHandlers;private String typeHandlersPackage;private Class<?>[] typeAliases;private String typeAliasesPackage;private Class<?> typeAliasesSuperType;......
}

我们看到该类实现了一个 FactoryBean、InitializingBean 的接口,下面分析这两个接口

FactoryBean 接口

分析 FactoryBean 接口,我们看到该接口共有三个方法需要实现,此处我们重点来关注一下 getObject() 方法

public interface FactoryBean<T> {// 该方法用来获取bean,即从Spring IOC容器中获取创建的bean,会调用到该方法@NullableT getObject() throws Exception;@NullableClass<?> getObjectType();default boolean isSingleton() {return true;}
}

FactoryBean 接口的作用:首先它是一个 bean,但又不仅仅是一个 bean。它是一个能生产或修饰对象生成的工厂 bean,类似于设计模式中的工厂模式和装饰器模式。它能在需要的时候生产一个 bean,且不仅仅限于它自身,它能返回任何 bean 的实例

FactoryBean 接口的详细分析:https://www.cnblogs.com/guitu18/p/11284894.html

InitializingBean 接口

在源码中,我们能够看到该接口有一个 afterPropertiesSet() 方法需要实现

public interface InitializingBean {void afterPropertiesSet() throws Exception;
}

该方法的作用:在 bean 的实例化和 bean 的属性填充完成后,执行的一些操作,该方法由 BeanFactory 调用。即创建工厂类的时候,一定会调用这个方法

getObject()afterPropertiesSet() 的实现

介绍完这两个接口,我们再来看看 getObject() 方法和 afterPropertiesSet() 方法在 SqlSessionFactoryBean 类中的具体实现过程

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {// 其他属性、方法 省略,仅展示要分析的源码 ......@Overridepublic SqlSessionFactory getObject() throws Exception {if (this.sqlSessionFactory == null) {// 1.第一步afterPropertiesSet();}return this.sqlSessionFactory;}@Overridepublic void afterPropertiesSet() throws Exception {notNull(dataSource, "Property 'dataSource' is required");notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),"Property 'configuration' and 'configLocation' can not specified with together");// 2.第二步this.sqlSessionFactory = buildSqlSessionFactory();}protected SqlSessionFactory buildSqlSessionFactory() throws IOException {Configuration configuration;// 3.第三步:XMLConfigBuilder 用来读取配置的 xmlConfigXMLConfigBuilder xmlConfigBuilder = null;if (this.configuration != null) {configuration = this.configuration;if (configuration.getVariables() == null) {configuration.setVariables(this.configurationProperties);} else if (this.configurationProperties != null) {configuration.getVariables().putAll(this.configurationProperties);}} else if (this.configLocation != null) {xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);configuration = xmlConfigBuilder.getConfiguration();} else {// 省略部分判断代码......}if (xmlConfigBuilder != null) {try {// 4.执行 xmlConfigBuilder.parse()方法,此处已经走入到 mybatis 源码部分,已经是MyBatis的执行流程了。xmlConfigBuilder.parse();if (LOGGER.isDebugEnabled()) {LOGGER.debug("Parsed configuration file: '" + this.configLocation + "'");}} catch (Exception ex) {throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);} finally {ErrorContext.instance().reset();}}if (!isEmpty(this.mapperLocations)) {for (Resource mapperLocation : this.mapperLocations) {if (mapperLocation == null) {continue;}try {// 5.解析 XMLMapper 映射器XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),configuration, mapperLocation.toString(), configuration.getSqlFragments());// 6.调用 xmlMapperBuilder.parse()方法,跳转到MyBatis源码去解析 XMLMapper 配置xmlMapperBuilder.parse();} catch (Exception e) {throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);} finally {ErrorContext.instance().reset();}}} else {if (LOGGER.isDebugEnabled()) {LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");}}// 7.通过sqlSessionFactoryBuilder.build()方法,创建一个sqlSessionFactoryreturn this.sqlSessionFactoryBuilder.build(configuration);}
}

build() 方法调用如下

public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);
}

DefaultSqlSessionFactory 类与 SqlSessionFactory 接口的关系

public class DefaultSqlSessionFactory implements SqlSessionFactory {private final Configuration configuration;public DefaultSqlSessionFactory(Configuration configuration) {this.configuration = configuration;}
}

通过如上代码分析,此处我们整理了一下,执行流程如下图所示

总结

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="configLocation" value="classpath:/resource/cfg.xml"/><property name="dataSource" ref="dataSource"/>
</bean>

配置完上面这个,它便会在 Spring 容器时启动创建 SqlSessionFactoryBean 时,调用 getObject() 等一系列方法,将全局配置文件和 mapper 配置文件等一些列操作在上面源码中都已经完成。最后调用了一个 return this.sqlSessionFactoryBuilder.build(configuration); 返回了一个 DefaultSqlSessionFactory 对象。此时创建 SqlSessionFactory 对象的任务就算完成了

Spring整合MyBatis之SqlSessionFactory对象的产生相关推荐

  1. Spring整合Mybatis之DAO层、Service层开发

    3. Spring整合Mybatis编程DAO层开发 1. 项目引入相关依赖spring mybatis mysql mybatis-spring druid2. 编写spring.xml整合:spr ...

  2. Spring整合MyBatis总结

    整合原理 MyBatis操作数据库,对数据库进行CRUD(增.删.改.查)操作时,实际原理是通过SqlSessionFactory对象---->产生SqlSession---->利用Sql ...

  3. Spring整合Mybatis之注解方式,(注解整合Junit)

    Spring整合Mybatis之注解方式 我有一篇博客详细写了我自己使用xml的方法Spring整合MyBatis,现在我就把核心配置文件中的每个bean的配置使用注解的方式实现 注解整合MyBati ...

  4. spring 整合 mybatis 中数据源的几种配置方式

    因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下. 一.采用org.mybatis.spring.mapp ...

  5. Spring 整合 Mybatis

    数据库环境 // 创建mybatis数据库 create database mybatis;use mybatis // 创建teacher表 create table teacher(id int ...

  6. 【Java从0到架构师】Spring - 整合 MyBatis

    整合 MyBatis 整合 MyBatis - 依赖 整合 MyBatis - 数据源 整合 MyBatis - SqlSessionFactoryBean 整合 MyBatis - MapperSc ...

  7. Spring——Spring整合MyBatis

    文章目录: 1.写在前面 2.实现步骤 2.1 项目的大体框架 2.2 使用Navicat在数据库中创建一张表student2 2.3 在pom.xml文件中加入maven依赖 2.4 编写实体类St ...

  8. Spring 整合 Mybatis - 二(切面、事务管理)

    紧接着上篇<Spring 整合 Mybatis - 一(基础)>,介绍Spring 整合 Mybatis的切面.事务管理. 1 增加切面aop功能 1.1 spring.xml sprin ...

  9. Spring 整合 Mybatis 原理

    目录 Mybatis的基本工作原理 分析需要解决的问题 Spring中Bean的产生过程 解决问题 解决方案 FactoryBean Import 总结 优化 Mybatis的基本工作原理 在 Myb ...

  10. Spring整合Mybatis注解方式

    Spring整合Mybatis(注解方式) 目录 Spring整合Mybatis(注解方式) 环境准备 纯注解方式 配置类具体内容 测试类具体内容 环境准备 jar包: Spring所需依赖:spri ...

最新文章

  1. GCC 连接器、链接标准库 gcc -l、链接手动创建库(指定目录的库 gcc -L)
  2. Linux下获取usb视频设备vendor id和product id的8种方法
  3. 位运算详解+竞赛常见用法总结
  4. js setTimeout()的使用
  5. java实现迷宫算法--转
  6. 这 6 个 Spring Boot 项目够经典
  7. linux 怎么重装libaprutil,Apache安装出错_cannot install `libaprutil-1.la' to a directory
  8. Knight Moves
  9. vs窗体 oracle,VS2010连接oracle数据库的简单例子
  10. 【剑指offer】面试题04:二维数组中的查找(java)
  11. power bulider 9.0 如何将sql语句查询的值返回给变量_SQL—你应该知道的子查询
  12. 6月全球浏览器份额之争:霸主IE份额持续降至54%
  13. linux 锐捷 dns,锐捷Linux
  14. matlab特征值分解
  15. SkeyeVSS综合安防监控Onvif、RTSP、GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览
  16. 一个刚毕业的大学生在一个陌生的城市如何租房?
  17. SQL 2014新功能介绍系列3 - 备份还原篇
  18. Kerberos介绍(全)
  19. Premiere视频片段剪辑、添加音乐、添加字幕
  20. 基于Mini无人机与改进损失函数的YOLO V3的大豆幼苗自动计数系统V1.0-使用手册

热门文章

  1. 极客大学架构师训练营 系统架构 大型网站技术架构 维基百科、淘宝、新浪微博案例分析 第8课 听课总结
  2. 计算机博弈军旗程序,军棋机器人UCT算法及计算机博弈行为研究
  3. linux安装unity桌面环境,Ubuntu 14.04 server安装桌面环境
  4. mysql exporter怎么配置_prometheus mysqld_exporter监控mysql-5.7
  5. 113. 路径总和 II
  6. 多路复用增益,PASTA定理
  7. 华为鸿蒙巴龙麒麟,华为5G新机强势曝光:麒麟985+巴龙5000+鸿蒙系统,颜值性能炸裂...
  8. 图像条纹检测 python_光源在外观缺陷检测中的应用
  9. RDN:Residual Dense Network for Image Super-Resolution
  10. 频谱感知4:CCS硬合并中m-out-of-K准则下m与K的联合优化问题