Spring企业应用之整合Mybatis

Mybatis原生方式使用

第一步:建立配置文件

主要配置Mybatis数据库参数、bean实体类、mapper文件以及其他特性。
配置分为以下几类:

  • configutation:根元素
  • properties:定义配置外在化
  • settings:一些全局性配置
  • typeAliases:为一些类定义别名
  • typeHandlers:定义类型处理,也就是定义Java类型与数据库中的数据类型之间的转换关系
  • objectFactory:用于指定结果集对象的实例是如何创建的
  • plugins:Mybatis的插件,插件可以修改Mybatis内部的运行规则
  • environments:环境
  • environment:配置Mybatis的环境
  • transactionManager:事务管理器
  • dataSource:数据源
  • mappers:指定映射文件或映射类
<!DOCTYPE mapper
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<configuration>
	<settings>
		<setting name="cacheEnabled" value="false"/>
		<setting name="useGeneratedKeys" value="true"/>
		<setting name="defaultExecutorType" value="REUSE"/>
	</settings>
	<typeAliases>
		<package alias="User" type="bean.User"/>
	</typeAliases>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC">
				<property name="..." value="..."/>
			</transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${username}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<package resource="resource/UserMapper.xml"/>
	</mappers>
</configuration>

第二步:建立实体对象

public class User {
        private int id;
        private String name;
        private int age;
        private String sex;

        //省略构造方法
        //省略构造函数和set/get方法
}

第三步:建立数据库操作映射Mapper接口类

public interface UserMapper {
	void insertUser(User user);
	User getUser(User user);
}

第四步:建立数据库操作映射Mapper的XML文件

<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Mapper.UserMapper">
	
	<select id="getUser" resultType="User" parameterType="java.lang.Integer">
		select * from user where id=#{id}
	</select>
	<insert id="insertUser" parameterType="User">
	    insert into user (name, age) values (
	    	#{name}, #{age}
	    )
	</insert>

</mapper>

第五步:开始使用

一个SQL的执行首先需要一个数据库连接,Mybatis通过sqlSessionFactory工厂类来创建一个sqlSession对象,来执行sql。而sqlSessionFactory工厂类的初始化需要读取Mybatis的配置文件,并使用SqlSessionFactoryBuilder建造者来创建,下面做一个简易的封装:

public class MyBatisUtil {
	private final static SqlSessionFactory sqlSessionFactory;

	static {
		String resource = "resource/mybatis-condig.xml";
		Reader reader = null;
		try {
			reader = Resources.getResourceAsReader(resource);
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}

		sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
	}

	public static SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}
}

这里很显然使用了工厂模式、建造者模式来创建SqlSession对象。
下面是一个调用UserMapper类执行sql的示例:

public class TestMapper {
	private static SqlSessionFactory sqlSessionFactory = null;

	static {
		sqlSessionFactory = MybatisUtil.getSqlSessionFactory();
	}

	public void testAdd() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
			User user = new User("Tom", new Integer(5));
			userMapper.insert(user);
			//提交
			sqlSession.commit();
		} finally {
			//关闭连接
			sqlSession.close();
		}
	}

	public void getUser() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
			User user = userMapper.getUser(1);
			System.out.println(user.toString());
		} finally {
			//关闭连接
			sqlSession.close();
		}
	}
}

sqlSession.getMapper()获取UserMapper实际上是获取UserMapper接口的动态代理实现类,这里使用了动态代理的设计模式,动态生成实现类,并绑定mapper.xml中的sql配置。

Spring整合Mybatis使用

mybatis-spring插件通过Spring对Mybatis的流程做了封装。

  • 增加SqlSessionFactoryBean来封装简化SqlSessionFactory的创建流程。
  • 增加MapperFactoryBean来封装简化Mapper的创建流程。内部是使用Mybatis的SqlSession类的getMapper()方法来获取对应的Mapper对象。

可将Mybatis中的基础配置移动到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" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${initialSize}" />
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${maxActive}" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${maxIdle}" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${minIdle}" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${maxWait}" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:test/mybatis/Mybatis-Configuration.xml" />
    </bean>

    <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="test.mybatis.dao.UserMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
       
</beans>

把数据源等配置移出Mybatis-Configuration配置文件,只保留实体类和mapper文件的映射关系:

<!DOCTYPE mapper
		PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
		"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<configuration>
	
	<typeAliases>
		<package alias="User" type="bean.User"/>
	</typeAliases>
	<mappers>
		<package resource="resource/UserMapper.xml"/>
	</mappers>
</configuration>

其他UserMapper的接口和UserMapper的SQL映射文件不变。

还可以进一步优化Mybatis-Configuration的配置文件,因为Spring提供了完整的Mybatis配置参数,因此相关的配置可以直接配置在SqlSessionFactoryBean中,支持configLocation、objectFactory、objectWrapperFactory、typeAliasesPackage、typeAliases、mapperLocations等参数。如下使用typeAliases和mapperLocations的Spring配置替换Mybatis-Configuration的配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 当mybatis的xml文件和mapper接口不在相同包下时,需要用mapperLocations属性指定xml文件的路径。  
         *是个通配符,代表所有的文件,**代表所有目录下 -->   
        <property name="mapperLocations" value="resource/*.xml" />
        <property name="typeAliases">
            <array>
                <value>bean.User</value>
            </array>
        </property> 
    </bean>

当然,Spring的封装优化不止于此,Spring还提供MapperScannerConfigurer类,自动扫描指定目录来创建Mapper接口映射。这是为了解决接口映射器过多的问题,通过扫描的方式可以自动创建MapperFactoryBean。
例如下面的配置将MapperFactoryBean替换成了MapperScannerConfigurer的配置:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="test.mybatis.dao" />
        <!-- 如果有多个数据源,需要增加此配置 -->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

最终只有1个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" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
                        http://www.springframework.org/schema/context  
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
                        http://www.springframework.org/schema/mvc  
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化连接大小 -->
        <property name="initialSize" value="${initialSize}" />
        <!-- 连接池最大数量 -->
        <property name="maxActive" value="${maxActive}" />
        <!-- 连接池最大空闲 -->
        <property name="maxIdle" value="${maxIdle}" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="${minIdle}" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="${maxWait}" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 当mybatis的xml文件和mapper接口不在相同包下时,需要用mapperLocations属性指定xml文件的路径。  
         *是个通配符,代表所有的文件,**代表所有目录下 -->   
        <property name="mapperLocations" value="resource/*.xml" />
        <property name="typeAliases">
            <array>
                <value>bean.User</value>
            </array>
        </property> 
    </bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="test.mybatis.dao" />
        <!-- 如果有多个数据源,需要增加此配置 -->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>   
</beans>

除此之外,Spring还提供了1个SqlSessionTemplate对象,实现了SqlSession接口,并提供了默认的模板方法实现。也可借助继承SqlSessionDaoSupport抽象类,这个抽象类里包含1个SqlSession对象,实际上默认的实例也是1个SqlSessionTemplate对象,这两种用法比较少见,不做过多介绍。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×