MyBatis-03-整合

MyBatis-03-整合回顾:任务目标一. Spring整合MyBatis1、mybatis-spring.jar2、SqlSessionFactoryBean2.1、SqlSessionFactoryBean的初始化2.2、获取SqlSessionFactoryBean实例3、MapperFactoryBean4、MapperScannerConfigurer5、SqlSessionTemplate二、Spring整合MyBatis应用1、功能描述2、创建工程3、数据库表结构及数据记录4、实例对象5、配置文件6、测试执行,输出结果复习作业面试题

回顾:

1. 掌握MyBatis动态SQL
2. 掌握MyBatis关联映射
3. 掌握MyBatis延迟加载
4. 掌握MyBatis缓存

任务

1. Spring整合MyBatis框架的配置详解
2. Spring整合MyBatis框架的具体应用

目标

1. 掌握Spring整合MyBatis框架的配置详解
2. 掌握Spring整合MyBatis框架的具体应用

一. Spring整合MyBatis

​ Spring在整合MyBatis时,需要一些jar包以及API,接下来介绍常用的jar包以及API

1、mybatis-spring.jar

​ 整合spring与mybatis框架的工具包

2、SqlSessionFactoryBean

​ 通过分析整合示例中的配置文件,我们可以知道配置的bean其实是成树状结构的,而在树的最顶层是类型为org.mybatis.spring.SqlSessionFactoryBean的bean,它将其他相关bean组装在了一起,那么,我们的分析就从此类开始。

SqlSessionFactoryBean这个类实现了三个接口,一个是InitializingBean,另一个是FactoryBean,还有就是ApplicationListener接口。下面说明一下实现了这三个接口的有什么作用

  1. InitializingBean接口:实现了这个接口,那么当bean初始化的时候,spring就会调用该接口的实现类的afterPropertiesSet方法,去实现当spring初始化该Bean的时候所需要的逻辑。
  2. FactoryBean接口:实现了该接口的类,在调用getBean的时候会返回该工厂返回的实例对象,也就是再调一次getObject方法返回工厂的实例。
  3. ApplicationListener接口:实现了该接口,如果注册了该监听的话,那么就可以了监听到Spring的一些事件,然后做相应的处理
2.1、SqlSessionFactoryBean的初始化
 

​ 从中我们可以看到,sqlSessionFactory的实例化便在这个方法里面实例化,buildSqlSessionFactory()方法会对我们的sqlSessionFactory做定制的初始化,初始化sqlSessionFactory有两种方式,一种是我们直接通过property直接注入到该实例中,另一种是通过解析xml的方式,就是我们在configuration.xml里面的配置,根据这些配置做了相应的初始化操作,里面也是一些标签的解析属性的获取,操作,和Spring的默认标签解析有点类似。

​ 从buildSqlSessionFactory函数中可以看到,尽管我们还是习惯于将MyBatis的配置与Spring的配置独立出来,但是,这并不代表Spring中的配置不支持直接配置。也就是说,你完全可以取消配置中的configLocation属性,而把其中的属性直接写在SqlSessionFactoryBean中。配置文件还可以支持其他多种属性的配置,如configLocation、objectFactory、objectWrapperFactory、typeAliasesPackage、typeAliases、typeHandlersPackage、plugins、typeHandlers、transactionFactory、databaseIdProvider、mapperLocations。但是,为了体现Spring更强大的兼容性,Spring还整合了MyBatis中其他属性的注入,并通过实例configuration来承载每一步所获取的信息并最终使用sqlSessionFactoryBuilder实例根据解析到的configuration创建SqlSessionFactory实例。

2.2、获取SqlSessionFactoryBean实例
 

​ 在给dao注入sqlSessionFactory的时候,依赖填写SqlSessionFactoryBean的实例就可以了。

3、MapperFactoryBean

​ 首先,我们需要从Mybatis官网上下载Mybatis-Spring的jar包添加到我们项目的类路径下,当然也需要添加Mybatis的相关jar包和Spring的相关jar包。我们知道在Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的。但是Mybatis-Spring是基于SqlSessionFactoryBean的。在使用Mybatis-Spring的时候,我们也需要SqlSession,而且这个SqlSession是内嵌在程序中的,一般不需要我们直接访问。SqlSession也是由SqlSessionFactory来产生的,但是Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息。所以接下来我们需要在Spring的applicationContext配置文件中定义一个SqlSessionFactoryBean。

Xml代码 :

 

​ 在定义SqlSessionFactoryBean的时候,dataSource属性是必须指定的,它表示用于连接数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:

Xml代码

 

​ 接下来就是在Spring的applicationContext文件中定义我们想要的Mapper对象对应的MapperFactoryBean了。通过MapperFactoryBean可以获取到我们想要的Mapper对象。MapperFactoryBean实现了Spring的FactoryBean接口,所以MapperFactoryBean是通过FactoryBean接口中定义的getObject方法来获取对应的Mapper对象的。在定义一个MapperFactoryBean的时候有两个属性需要我们注入,一个是Mybatis-Spring用来生成实现了SqlSession接口的SqlSessionTemplate对象的sqlSessionFactory;另一个就是我们所要返回的对应的Mapper接口了。

​ 定义好相应Mapper接口对应的MapperFactoryBean之后,我们就可以把我们对应的Mapper接口注入到由Spring管理的bean对象中了,比如Service bean对象。这样当我们需要使用到相应的Mapper接口时,MapperFactoryBean会从它的getObject方法中获取对应的Mapper接口,而getObject内部还是通过我们注入的属性调用SqlSession接口的getMapper(Mapper接口)方法来返回对应的Mapper接口的。这样就通过把SqlSessionFactory和相应的Mapper接口交给Spring管理实现了Mybatis跟Spring的整合。

Spring的applicationContext.xml配置文件:

Xml代码

 

BlogMapper.xml文件

Xml代码

 

BlogMapper.java:

Java代码 :

 

BlogServiceImpl.java:

Java代码

 
4、MapperScannerConfigurer

​ 利用上面的方法进行整合的时候,我们有一个Mapper就需要定义一个对应的MapperFactoryBean,当我们的Mapper比较少的时候,这样做也还可以,但是当我们的Mapper相当多时我们再这样定义一个个Mapper对应的MapperFactoryBean就显得速度比较慢了。为此Mybatis-Spring为我们提供了一个叫做MapperScannerConfigurer的类,通过这个类Mybatis-Spring会自动为我们注册Mapper对应的MapperFactoryBean对象。

​ 如果我们需要使用MapperScannerConfigurer来帮我们自动扫描和注册Mapper接口的话我们需要在Spring的applicationContext配置文件中定义一个MapperScannerConfigurer对应的bean。对于MapperScannerConfigurer而言有一个属性是我们必须指定的,那就是basePackage。basePackage是用来指定Mapper接口文件所在的基包的,在这个基包或其所有子包下面的Mapper接口都将被搜索到。多个基包之间可以使用逗号或者分号进行分隔。最简单的MapperScannerConfigurer定义就是只指定一个basePackage属性,如:

Xml代码

 

​ 这样MapperScannerConfigurer就会扫描指定基包下面的所有接口,并把它们注册为一个个MapperFactoryBean对象。当使用MapperScannerConfigurer加basePackage属性的时候,我们上面例子的applicationContext配置文件将变为这样:

Xml代码

 

​ 有时候我们指定的基包下面的并不全是我们定义的Mapper接口,为此MapperScannerConfigurer还为我们提供了另外两个可以缩小搜索和注册范围的属性。一个是annotationClass,另一个是markerInterface。

​ 如果上述两个属性都指定了的话,那么MapperScannerConfigurer将取它们的并集,而不是交集。即使用了annotationClass进行标记或者继承自markerInterface的接口都将被注册为一个MapperFactoryBean。

​ 现在假设我们的Mapper接口都继承了一个SuperMapper接口,那么我们就可以这样来定义我们的MapperScannerConfigurer。

Xml代码

 

​ 如果是都使用了注解MybatisMapper标记的话,那么我们就可以这样来定义我们的MapperScannerConfigurer。

Xml代码

 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
    <property name="basePackage" value="com.qfmybatis.mapper" />  
    <property name="annotationClass" value="com.qfmybatis.annotation.MybatisMapper"/>  
 </bean>

​ 除了用于缩小注册Mapper接口范围的属性之外,我们还可以指定一些其他属性,如:

注意:由于使用sqlSessionFactory和sqlSessionTemplate属性时会使一些内容在PropertyPlaceholderConfigurer之前加载,导致在配置文件中使用到的外部属性信息无法被及时替换而出错,因此官方现在新的Mybatis-Spring中已经把sqlSessionFactory和sqlSessionTemplate属性废弃了,推荐大家使用sqlSessionFactoryBeanName属性和sqlSessionTemplateBeanName属性。

Xml代码

 
5、SqlSessionTemplate

​ 除了上述整合之后直接使用Mapper接口之外,Mybatis-Spring还为我们提供了一种直接使用SqlSession的方式。Mybatis-Spring为我们提供了一个实现了SqlSession接口的SqlSessionTemplate类,它是线程安全的,可以被多个Dao同时使用。同时它还跟Spring的事务进行了关联,确保当前被使用的SqlSession是一个已经和Spring的事务进行绑定了的。而且它还可以自己管理Session的提交和关闭。当使用了Spring的事务管理机制后,SqlSession还可以跟着Spring的事务一起提交和回滚。

​ 使用SqlSessionTemplate时我们可以在Spring的applicationContext配置文件中如下定义:

 

​ 这样我们就可以通过Spring的依赖注入在Dao中直接使用SqlSessionTemplate来编程了,这个时候我们的Dao可能是这个样子:

Java代码

 

二、Spring整合MyBatis应用

​ 前面讲到有关 mybatis 连接数据库,然后进行进行数据增删改查,以及多表联合查询的例子,但很多的项目中,通常会用 spring 这个粘合剂来管理 datasource 等。充分利用 spring 基于接口的编程,以及aop ,ioc 带来的方便。用 spring 来管理 mybatis 与管理 hibernate 有很多类似的地方。在这一节中,我们重点介绍数据源管理以及 bean 的配置。

​ 整个Mybatis与Spring集成示例要完成的步骤如下:

1、功能描述

​ 需要完成这样的一个简单功能,即,指定一个用户(ID=1),查询出这个用户的基本信息,并关联查询这个用户的所有订单。

2、创建工程

​ 首先创建一个工程的名称为:mybatis07-spring,在 src 源代码目录下建立文件夹 config,并将原来的 mybatis 配置文件 Configuration.xml 移动到这个文件夹中, 并在 config 文家夹中建立 Spring 配置文件:applicationContext.xml。

3、数据库表结构及数据记录

在本示例中,用到两个表:用户表和订单表,其结构和数据记录如下:

 

订单表结构和数据如下:

 
4、实例对象

用户表和订单表分别对应两个实例对象,分别是:User.java 和 Order.java,它们都在 com.qf.pojo 包中。

User.java代码内容如下:

 

Order.java代码内容如下:

 
5、配置文件

这个实例中有三个重要的配置文件,它们分别是:applicationContext.xml , Configuration.xml 以及 UserMaper.xml。

applicationContext.xml 配置文件里最主要的配置:

 

配置文件 Configuration.xml 的内容如下:

 

UserMaper.xml 用于定义查询和数据对象映射,其内容如下:

 
6、测试执行,输出结果

我们创建一个测试类为:Main.java , 就在 src 目录中。其代码如下:

 

运行结果如下:

 

复习

1. MyBatis动态SQL的使用
2. MyBatis关联映射的配置

作业

1.  使用Spring整合MyBatis框架改写昨天的作业

面试题

1. Spring框架与MyBatis框架整合的方案
2. @MapperScan注解的作用
3. Mybatis关联映射的使用
4. ResultType和ResultMap的区别