
摘要: 本文结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码。若有描述错误之处,欢迎指正。
了解了MyBatis的独立使用过程后,我们再看看它与Spring整合的使用方式,比对之前的示例来找出Spring究竟为我们做了哪些操作来简化程序员的业务开发。由于在之前示例基础上做更改,所以,User与UserMapper保持不变。
(1)Spring配置文件。
配置文件是Spring的核心,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.xsd"> <!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"
lazy-init="true">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/> <!-- 配置连接池初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.initialSize}"/>
<property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
<!-- 配置获取连接等待超时的时间,单位是毫秒 -->
<property name="maxWait" value="${jdbc.maxWait}"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
<property name="validationQuery" value="select 1"/>
<property name="testWhileIdle" value="${jdbc.testWhileIdle}"/>
<property name="testOnBorrow" value="${jdbc.testOnBorrow}"/>
<property name="testOnReturn" value="${jdbc.testOnReturn}"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}"/>
<property name="maxPoolPreparedStatementPerConnectionSize"
value="${jdbc.maxPoolPreparedStatementPerConnectionSize}"/>
<!-- 统计sql filter -->
<property name="proxyFilters">
<list>
<bean class="com.alibaba.druid.filter.stat.StatFilter">
<property name="mergeSql" value="true"/>
<property name="slowSqlMillis" value="${jdbc.slowSqlMillis}"/>
<property name="logSlowSql" value="true"/>
</bean>
</list>
</property>
</bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean> <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.cellphone.uc.repo.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean> </beans>
对比之前独立使用MyBatis的配置文件,我们发现,之前在environments中设置的dataSource被转移到了Spring的核心配置文件中管理。而且,针对于MyBatis,注册了org.mybatis.spring.SqlSessionFactoryBean类型bean,以及用于映射接口的org.mybatis.spring.mapper.MapperFactoryBean,这两个bean的作用我们会在稍后分析。
之前我们了解到,MyBatis提供的配置文件包含了诸多属性,虽然大多数情况我们都会保持MyBatis原有的风格,将MyBatis的配置文件独立出来,并在Spring中的org.mybatis.spring.SqlSessionFactoryBean类型的bean中通过configLocation属性引入,但是,这并不代表Spring不支持直接配置。以上面示例为例,你完全可以省去mybatis-config.xml,而将其中的配置以属性的方式注入到SqlSessionFactoryBean中,至于每个属性名称以及用法,我们会在后面的章节中进行详细的分析。
(2)MyBatis配置文件。
对比独立使用MyBatis时的配置文件,当前的配置文件除了移除environments配置外并没有太多的变化。
<?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>
<!--设置-->
<settings>
<setting name="cacheEnabled" value="false"/>
<setting name="useGeneratedKeys" value="true"/>
<setting name="defaultExecutorType" value="REUSE"/>
</settings>
<!--类型命名-->
<typeAliases>
<typeAlias alias="User" type="org.cellphone.uc.repo.po.User"/>
</typeAliases>
<!--映射器-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
(3)映射文件(保持不变)。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.cellphone.uc.repo.mapper.UserMapper">
<resultMap id="BaseResultMap" type="org.cellphone.uc.repo.po.User">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Apr 21 15:38:35 CST 2018.
-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="age" jdbcType="INTEGER" property="age" />
</resultMap> <sql id="Base_Column_List">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Apr 21 15:38:35 CST 2018.
-->
id, username, age
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Apr 21 15:38:35 CST 2018.
-->
select
<include refid="Base_Column_List" />
from user
where id = #{id,jdbcType=BIGINT}
</select>
<insert id="insert" parameterType="org.cellphone.uc.repo.po.User">
<!--
WARNING - @mbg.generated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Sat Apr 21 15:38:35 CST 2018.
-->
insert into user (id, username, password,
sex, age, status, create_tm
)
values (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}
)
</insert>
</mapper>
(4)测试。
至此,我们已经完成了Spring与 MyBatis的整合,我们发现,对于MyBatis方面的配置文件,除了将dataSource配置移到Spring配置文件中管理外,并没有太多变化,而在Spring的配置文件中又增加了用于处理MyBatis的两个bean。
Spring整合MyBatis的优势主要在于使用上,我们来看看Spring中使用MyBatis的用法。
public class UserServiceTest { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring/application.xml");
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
User user = userMapper.selectByPrimaryKey(32L);
System.out.println("name: " + user.getUsername() + "| age: " + user.getAge());
}
}
测试中我们看到,在Spring中使用MyBatis非常方便,用户甚至无法察觉自己正在使用MyBatis,而这一切相对于独立使用MyBatis时必须要做的各种冗余操作来说无非是大大简化了我们的工作量。