10.1 整合环境搭建

Spring和MyBatis的整合主要涉及准备所需的JAR包和编写配置文件,下面将详细介绍。

10.1.1 准备所需的JAR包

要实现MyBatis与Spring的整合,需要这两个框架相关的JAR包,除此之外,还需要其他的JAR包来配合使用。
1.所需Spring框架的JAR包
Spring框架所需要准备的JAR包共10个,其中包括4个核心模块JAR、AOP开发使用的JAR、JDBC和事务的JAR(其中核心容器依赖的commons-logging的JAR在MyBatis框架的lib包中已经包含),具体如下所示。
•  aopalliance-1.0.jar
•  aspectjweaver-1.8.10.jar
•  spring-aop-4.3.6.RELEASE.jar
•  spring-aspects-4.3.6.RELEASE.jar
•  spring-beans-4.3.6.RELEASE.jar
•  spring-context-4,3.6.RELEASE.jar
•  spring-core-4.3.6.RELEASE.jar
•  spring-expression-4.3.6.RELEASE.jar
•  spring-jdbc-4.3.6.RELEASE.jar
•  spring-tx-4.3.6.RELEASE.jar
2.所需MyBatis框架的JAR包
MyBatis框架需要准备的JAR包共13个,其中包括核心包mybatis-3.4.2.jar及其解压文件夹中lib目录中的所有JAR,具体如下所示。
•  ant-1.9.6.jar
•  ant-launcher-1.9.6.jar
•  asm-5.1.jar
•  cglib-3.2.4.jar
•  commons-logging-1.2.jar
•  javassist-3.21.0-GA.jar
•  log4j-1.2.17.jar
•  log4j-api-2.3ar
•  log4j-core-2.3.jar
•  mybatis-3.4.2.jar
•  ognl-3.1.12.jar
•  slf4j-api-1.7.22.jar
•  slf4j-log4j12-1.7.22.jar
3.MyBatis与Spring整合所需的中间JAR包
为了满足MyBatis用户对Spring框架的需求,MyBatis社区开发了一个用于整合MyBatis和Spring两个框架的中间件——MyBatis-Spring。
本书使用的中间件是mybatis-spring-1.3.1jar。此版本的JAR包可以通过链接获取https://mvnrepository.com/artifact/org.mybatis/mybatis-spring/1.3.1。
4.数据库驱动JAR包
本书所使用的数据库驱动包为mysql-connector-java-5.1.7-bin.jar。
5.数据源所需JAR包
整合时所使用的是DBCP数据源,所以需要准备DBCP和连接池的JAR包,具体如下所示。
•  commons-dbcp2-2.1.1.jar
•  commons-pool2-2.4.2.jar

10.1.2 编写配置文件

在Eclipse中创建一个名称为chapter10的Web项目,将10.1.1小节准备的全部JAR包添加到项目的lib目录中,并发布到类路径下。

【示例10-1】参照前面章节的内容和案例,在项目的src目录下分别创建db.properties文件、Spring的配置文件applicationContext.xml以及MyBatis的配置文件mybatis-config.xml,如文件10.1、10.2和10.3所示。

文件10.1 db.properties

springbatch step 参数 springbatis_spring

在文件10.1中,除了配置连接数据库的基本4项外,还配置数据库连接池的最大连接数(maxTotal)、最大空闲连接数(maxIdle)以及初始化连接数(initialSize)。

文件10.2 applicationContext.xml

springbatch step 参数 springbatis_mybatis_02

springbatch step 参数 springbatis_springbatch step 参数_03

在文件10.2中,首先定义了读取properties文件的配置,然后配置了数据源,接下来配置了事务管理器并开启了事务注解,最后配置了MyBatis工厂来与Spring整合。其中,MyBatis工厂的作用是构建SqlSessionFactory,它是通过MyBatis-Spring包中提供的org.mybatis.Spring.SqlSessionFactoryBean类来配置的。通常在配置时需要提供两个参数:一个是数据源;另一个是MyBatis的配置文件路径。这样Spring的IoC容器就会在初始化id为sqlSessionFactory的Bean时解析MyBatis的配置文件,并与数据源一同保存到Spring的Bean中。

文件10.3 mybatis-config.xml

springbatch step 参数 springbatis_springbatch step 参数_04

由于在Spring中已经配置了数据源信息,因此在MyBatis的配置文件中不再需要配置数源信息。这里只需要使用和元素来配置文件别名以及指定mapper文件位置即可。

此外,还需在项目的src目录下创建log4j.properties文件,该文件的编写可参考第6章的入门案例,也可将前面章节创建的该文件复制到此项目中使用。


10.2 整合

10.1节已经完成了对MyBatis与Spring整合环境的搭建工作,可以说完成这些配置后就已经完成了这两个框架大部分的整合工作。接下来,本节将对通过传统DAO方式和Mapper接口方式的开发整合进行介绍。

10.2.1 传统DAO方式的开发整合

采用传统DAO开发方式进行MyBatis与Spring框架的整合时,我们需要编写DAO接口以及接口的实现类,并且需要向DAO实现类中注入SqlSessionFactory,然后在方法体内通过SqlSessionFactory创建SqlSession。为此,我们可以使用Mybatis-Spring包中所提供的SqlSessionTemplate类或SqlSessionDaoSupport类来实现此功能。这两个类的描述如下。

•  SqlSessionTemplate:Mybatis-Spring的核心类,它负责管理MyBatis的SqlSession,调用MyBatis的SQL方法。当调用SQL方法时,SqlSessionTemplate将会保证使用的SqlSession和当前Spring的事务是相关的。它还管理SqlSession的生命周期,包含必要的关闭、提交和回滚操作。

•  SqlSessionDaoSupport:一个抽象支持类,它继承了DaoSupport类,主要是作为DAO的基类来使用。可以通过SqlSessionDaoSupport类的getSqlSession()方法来获取所需的SqlSession。

【示例10-2】了解了传统DAO开发方式整合可以使用的两个类后,下面以SqlSessionDaoSupport类的使用为例讲解传统的DAO开发方式整合的实现,其具体步骤如下。

1.实现持久层

步骤01 在src目录下创建一个com.ssm.po包,并在包中创建持久化类用户类User,在User类中定义相关属性和方法,如文件10.4所示。

文件10.4 User.java

springbatch step 参数 springbatis_java_05

步骤02 在com.ssm.po包中创建映射文件UserMapper.xml,在该文件中编写根据id查询用户信息的映射语句,如文件10.5所示。

文件10.5 UserMapper.xml

springbatch step 参数 springbatis_spring_06

步骤03 在MyBatis的配置文件mybatis-config.xml中配置映射文件UserMapper.xml的位置,具体如下。

<mapper resource="com/ssm/po/UserMapper.xml" />

2.实现DAO层

步骤01 在src目录下创建一个com.ssm.dao包,并在包中创建接口UseDao,在接口中编写一个通过id查询用户的方法findUserById(),如文件10.6所示。

文件10.6 UserDao.iava

springbatch step 参数 springbatis_mybatis_07

步骤02 在src目录下创建一个com.ssm.dao.impl包,并在包中创建UserDao接口的实现类UserDaoImpl,如文件10.7所示。

文件10.7 UserDaoImpl.java

springbatch step 参数 springbatis_mybatis_08

在文件10.7中,UserDaoImpl类继承了SqlSessionDaoSupport并实现了UserDao接口。其中,SqlSessionDaoSupport类在使用时需要一个SqlSessionFactory或一个SqlSessionTemplate对象,所以需要通过Spring给SqlSessionDaoSupport类的子类对象注入一个SqlSessionFactory或SqlSessionTemplate。这样,子类中就能通过调用SqlSessionDaoSupport类的getSqlSession()方法来获取SqlSession对象,并使用SqlSession对象中的方法了。
步骤03 在Spring的配置文件applicationContext.xml中编写实例化UserDaoImpl的配置,代码如下所示。

<!-- 实例化Dao -->
<bean id="userDao" class="com.ssm.dao.impl.UserDaoImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>

上述代码创建了一个id为userDao的Bean,并将SqlSessionFactory对象注入该Bean的实例化对象中。

3.整合测试

在src目录下创建一个com.ssm.test包,在包中创建测试类UserDaoTest,并在类中编写测试方法findUserByIdDaoTest(),如文件10.8所示。

文件10.8 DaoTest.java

springbatch step 参数 springbatis_spring_09

在上述方法中,我们采用的是根据容器中Bean的id来获取指定Bean的方式。执行上述方法后,控制台的输出结果如图10.1所示。从中可以看出,通过UserDao实例的findUserById()方法已经查询出了id为1的用户信息,这就说明MyBatis与Spring整合成功。

springbatch step 参数 springbatis_jar_10

图10.1 运行结果

10.2.2 Mapper接口方式的开发整合

在MyBatis+Spring的项目中,虽然使用传统的DAO开发方式可以实现所需功能,但是采用这种方式在实现类中会出现大量的重复代码,在方法中也需要指定映射文件中执行语句的id,并且不能保证编写时id的正确性(运行时才能知道)。为此,我们可以使用MyBatis提供的另一种编程方式,即使用Mapper接口编程。接下来将讲解如何使用 Mapper接口方式来实现MyBatis与Spring的整合。

1.基于MapperFactoryBean的整合

MapperFactoryBean是MyBatis-Spring团队提供的一个用于根据Mapper接口生成Mapper对象的类,该类在Spring配置文件中使用时可以配置以下参数。

•  mapperInterface:用于指定接口。

•  SqlSessionFactory:用于指定SqlSessionFactory。

•  SqlSessionTemplate:用于指定SqlSessionTemplate。若与SqlSessionFactory同时设定,则只会启用SqlsessionTemplate。

【示例10-3】了解了MapperFactoryBean类后,接下来通过一个具体的案例来演示如何通过MapperFactoryBean实现MyBatis与Spring的整合,具体步骤如下。

步骤01 在src目录下创建一个com.ssm.mapper包,然后在该包中创建UserMapper接口以及对应的映射文件,如文件10.9和文件10.10所示。

文件10.9 UserMapper.java

springbatch step 参数 springbatis_jar_11

文件10.10 UserMapper.xml

springbatch step 参数 springbatis_java_12

从文件10.9和文件10.10可以看出,这两个文件的实现代码与10.2.1小节中UserDao接口以及映射文件UserMapper.xml的实现代码基本相同,只是本案例与10.2.1小节的案例的区别在于,本案例将接口文件改名并与映射文件一起放在了com.ssm.mapper包中。

步骤02 在MyBatis的配置文件中引入新的映射文件,代码如下所示。

springbatch step 参数 springbatis_spring_13

步骤03 在Spring的配置文件中创建一个id为userMapper的Bean,代码如下所示。

springbatch step 参数 springbatis_java_14

上述配置代码为MapperFactoryBean指定了接口以及SqlSessionFactory。

步骤04 在测试类UserDaoTest中编写测试方法findUserByIdMapperTest(),其代码如下所示。

springbatch step 参数 springbatis_springbatch step 参数_15

上述方法中,通过Spring容器获取了UserMapper实例,并调用了实例中的findUserById()方法来查询id为1的用户信息。执行方法后,控制台的输出结果与图10.1相同。

注意

Mapper接口编程方式是,只需要程序员编写Mapper接口(相当于DAO接口),然后由MyBatis框架根据接口的定义创建接口的动态代理对象,这个代理对象的方法体等同于10.2.1小节中DAO接口的实现类方法。

虽然使用Mapper接口编程的方式很简单,但是在具体使用时还是需要遵循以下规范。

(1)Mapper接口的名称和对应的Mapper.xml映射文件的名称必须一致。

(2)Mapper.xml文件中的namespace与Mapper接口的类路径相同(即接口文件和映射文件需要放在同一个包中)。

(3)Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同。

(4)Mapper接口中方法的输入参数类型要和Mapper.xml中定义的每个SQL的parameterType的类型相同。

(5)Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个SQL的resultType的类型相同。

只要遵循了这些开发规范,MyBatis就可以自动生成Mapper接口实现类的代理对象,从而简化开发。

2.基于MapperScannerConfigurer的整合

在实际的项目中,DAO层会包含很多接口,如果每一个接口都像10.2.1小节中那样在Spring配置文件中配置,那么不但会增加工作量,还会使得Spring配置文件非常臃肿。为此,MyBatis-Spring团队提供了一种自动扫描的形式来配置MyBatis中的映射器——采用MapperScannerConfigurer类。

MapperScannerConfigurer类在Spring配置文件中使用时可以配置以下属性。

•  basePackage:指定映射接口文件所在的包路径,当需要扫描多个包时可以使用分号或逗号作为分

隔符。指定包路径后,会扫描该包及其子包中的所有文件。

•  annotationClass:指定要扫描的注解名称,只有被注解标识的类才会被配置为映射器。

•  sqlSessionFactoryBeanName:指定在Spring中定义的SqlSessionFactory的Bean名称。

•  sqlSessionTemplateBeanName:指定在Spring中定义的SqlSessionTemplate的Bean名称。若定义此属性,则sqlSessionFactoryBeanName将不起作用。

•  markerInterface:指定创建映射器的接口。

MapperScannerConfigurer的使用非常简单,只需要在Spring的配置文件中编写如下代码:

springbatch step 参数 springbatis_spring_16

在通常情况下,MapperScannerConfigurer在使用时只需通过basePackage属性指定需要扫描的包即可。Spring会自动地通过包中的接口生成映射器。这使得开发人员可以在编写很少代码的情况下完成对映射器的配置,从而提高开发效率。
要验证上面的配置很容易,只需将上述配置代码写入Spring的配置文件,并将基于MapperFactoryBean的整合案例中的步骤02和步骤03的代码注释掉,再次执行findUserByIdMapperTest()方法进行测试即可。方法执行后结果一致。