摘要: 本文结合《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时必须要做的各种冗余操作来说无非是大大简化了我们的工作量。