1、MyBatis-Spring简介:
MyBatis-Spring帮助你无缝地整合MyBatis代码到Spring中。使用这个类库中的类,Spring将会加载必要的MyBatis工厂类和session 类。
这个类库也提供一个简单的方式来注入MyBatis数据映射器和SqlSession到业务层的bean中。而且它也会处理事务,翻译MyBatis
异常到Spring的DataAccessException异常(数据访问异常,译者注)。最终,它不依赖于MyBatis,Spring或MyBatis-Spring来构建应用程序代码。
2、要使用MyBatis-Spring模块,你只需要包含mybatis-spring-1.0.0.jar(现在已经更新到mybatis-spring-1.2.1)文件,并在类路径中加入依赖关系。
要和Spring一起使用MyBatis,你需要在Spring应用上下文中定义至少两样东西:一个SqlSessionFactory和至少一个数据映射器类。
在MyBatis-Spring中,SqlSessionFactoryBean是用于创建SqlSessionFactory的。要配置这个工厂bean,
放置下面的代码在Spring的XML配置文件中:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> </bean>
要注意SqlSessionFactory需要一个DataSource(数据源)。这可以是任意
的DataSource,配置它就和配置其它Spring数据库连接一样。如下:
<!-- 数据库配置文件位置 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 配置dbcp数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <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="minIdle" value="${jdbc.minIdle}"></property> <!-- 队列中的最大等待数 --> <property name="maxIdle" value="${jdbc.maxIdle}"></property> <!-- 最长等待时间,单位毫秒 --> <property name="maxWait" value="${jdbc.maxWait}"></property> <!-- 最大活跃数 --> <property name="maxActive" value="${jdbc.maxActive}"></property> <property name="initialSize" value="${jdbc.initialSize}"></property> </bean>
public interface userMapper { public Login login(Login login); }
那么可以使用MapperFactoryBean,像下面这样来把接口加入到Spr ing中:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
要注意指定的映射器类必须是一个接口,而不是具体的实现类。在这个示例中,使用MyBatis的映射器XML文件来指定sql语句,
但是用注解用来指定SQL语句也是可以的。
一旦配置好,你可以用注入其它任意Spring的bean相同的方式直接注入映射器到你的business/ser vice对象中。
MapperFactoryBean处理SqlSession的创建和关闭它。如果使用了Spring 的事务,那么当事务完成时,
session 将会提交或回滚。最终,任何异常都会被翻译成Spring的DataAccessException异常。
调用MyBatis数据方法现在只需一行代码(一般是在使用工厂模式的Service实现的时候):
public class FooServiceImpl implements FooService { private UserMapper userMapper; public void setUserMapper(UserMapper userMapper) { this.userMapper = userMapper; } public User doSomeBusinessStuff(String userId) { return this.userMapper.getUser(userId); } }
3、现在还简单介绍一下上面的SqlSessionFactoryBean,这个是核心的:
3.1、在基本的MyBatis中,session 工厂可以使用SqlSessionFactoryBuilder.来创建。
在MyBatis-Spring中,使用了SqlSessionFactoryBean来替代。
要创建工厂bean,放置下面的代码在Spring的XML配置文件中:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> </bean>
要注意SqlSessionFactoryBean实现了Spring的FactoryBean接口。这就说明由Spring最终创建的bean不是SqlSessionFactoryBean本
然后将它以SqlSessionFactory为名来存储。在Java中,相同的代码是:
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); SqlSessionFactory sessionFactory = factoryBean.getObject();
在一般的MyBatis-Spring用法中,你不需要直接使用SqlSessionFactoryBean或和其对
应的SqlSessionFactory。相反,session工厂将会被注入到MapperFactoryBean或其它扩3.1、现在再看看数据源的配置及一些属性:
SqlSessionFactory有一个单独的必须属性,就是JDBC的DataSource。这可以是任意
的DataSource,其配置应该和其它Spring数据库连接是一样的。
一个通用的属性是configLocation,它是用来指定MyBatis的XML配置文件路径的。
如果基本的MyBatis配置需要改变,那么这就是一个需要它的地方。通常这会是<settings>
或<typeAliases>的部分。
要注意这个配置文件不需要是一个完整的MyBatis配置。确定地说,任意环境,数据源
和MyBatis的事务管理器都会被忽略。SqlSessionFactoryBean会创建它自己的,使用这些
值定制MyBatis的Environment时是需要的。
如果MyBatis映射器XML文件在和映射器类相同的路径下不存在,那么另外一个需要
配置文件的原因就是它了。使用这个配置,有两种选择。第一是手动在MyBatis的XML配
置文件中使用<mappers>部分来指定类路径。第二是使用工厂bean的mapperLocations属
性。
mapperLocations属性使用一个资源位置的list。这个属性可以用来指定MyBatis的XML
映射器文件的位置。它的值可以包含Ant样式来加载一个目录中所有文件,或者从基路径下
递归搜索所有路径。比如:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" /> </bean>
这会从类路径下加载在sample.config.mappers 包和它的子包中所有的MyBatis映射器XML文件。
下面写上详细的一些简单配置:
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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd" default-autowire="byName"> <!-- 加载数据库配置文件,如果是Sqlserver数据库,请修改此值为Sqlserver.config --> <bean id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"> <property name="locations"> <list> <value> classpath:config/Oracle.properties </value> </list> </property> </bean> <!-- 获取数据源 dataSource --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </bean> <!-- 管理SqlSession,自动打开,关闭,提交,回滚等 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation"> <value>classpath:config/mybatis.xml</value> </property> <property name="dataSource" ref="dataSource"/> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <!-- <bean name="transactionManager" class="org.springframework.jdbc.datasource.DateSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="select*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* net.business.*.*(..))" id="aopConfig"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="aopConfig"/> </aop:config> --> </beans>Sqlserver数据库Sqlserver.properties如下:
driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver url=jdbc:sqlserver://localhost:1433; DatabaseName=dataName username=sa password=sa
mybatis的配置文件mybatis.xml 如下:
<?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="true" /> <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 --> <setting name="lazyLoadingEnabled" value="true" /> <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 --> <setting name="aggressiveLazyLoading" value="true" /> <!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) --> <setting name="multipleResultSetsEnabled" value="true" /> <!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 --> <setting name="useColumnLabel" value="true" /> <!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) --> <setting name="useGeneratedKeys" value="true" /> <!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) --> <setting name="autoMappingBehavior" value="PARTIAL" /> <!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 --> <setting name="defaultExecutorType" value="SIMPLE" /> <!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 --> <setting name="defaultStatementTimeout" value="25000" /> </settings> <!-- 别名定义 --> <typeAliases> <typeAlias alias="Login" type="net.system.Login" /> </typeAliases> <!-- 映射文件,存放sql语句的配置文件 --> <mappers> <mapper resource="net/system/Login.xml" /> </mappers> </configuration>
4、使用SqlSession
上面的说明中还有最重要的没有提了,那就是SqlSession 的实现了。
在MyBatis中,你可以使用SqlSessionFactory来创建SqlSession。一旦你获得一个
session 之后,你可以使用它来执行映射语句,提交或回滚连接,最后,当不再需要它的时
候,你可以关闭session。使用MyBatis-Spring之后,你不再需要直接使用SqlSessionFactory
了,因为你的bean可以通过一个线程安全的SqlSession来注入,基于Spring的事务配置
来自动提交,回滚,关闭session。
注意通常不必直接使用SqlSession。在大多数情况下MapperFactoryBean,将会在bean
中注入所需要的映射器。下一章节中的MapperFactoryBean会解释这个细节。
这里主要介绍两种,SqlSessionTemplate和SqlSessionSupport。
4.1、SqlSessionTemplate:
SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,
调用MyBatis的SQL方法,翻译异常。SqlSessionTemplate是线程安全的,可以被多个DAO
所共享使用。
当调用SQL方法时,包含从映射器getMapper()方法返回的方法,SqlSessionTemplate
将会保证使用的SqlSession是和当前Spring的事务相关的。此外,它管理session的生命
周期,包含必要的关闭,提交或回滚操作。
SqlSessionTemplate实现了SqlSession,这就是说要对MyBatis的SqlSession进行简易替换。
SqlSessionTemplate通常是被用来替代默认的MyBatis实现的DefaultSqlSession,
因为它不能参与到Spring 的事务中也不能被注入,因为它是线程不安全的。相同应用程序
中两个类之间的转换可能会引起数据一致性的问题。
SqlSessionTemplate对象可以使用SqlSessionFactory作为构造方法的参数来创建。
<!-- 配置mybitasSqlSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis.xml"></property> </bean> <!-- 配置SqlSessionTemplate --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
接下来看看去证明实现呢?
public class UserDaoImpl implements UserDao { private SqlSessionTemplate sqlSessionTemplate; public User findUserByid(Integer userId) { return sqlSessionTemplate.selectOne(FIND_USER_BYID, userId); } public List<User> findAll() { return sqlSessionTemplate.selectList(SELECT_ALL_USER); } public User userLogin(User user) { return sqlSessionTemplate.selectOne(USER_LOGIN, user); } }
如下注入SqlSessionTemplate:
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl"> <property name="sqlSession" ref="sqlSessionTemplate"/> </bean>
qlSessionDaoSupport 是一个抽象的支持类,用来为你提供SqlSession。调用
getSqlSession()方法你会得到一个SqlSessionTemplate,之后可以用于执行SQL方法,
就像下面这样:
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { public User getUser(String userId) { return (User) getSqlSession() .selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); } }
假设类UserMapperImpl是SqlSessionDaoSupport的子类,它可以在Spring中进行如下的配置:
<bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserMapperImpl"> <!--注入SqlSessionTemplate实例 --> <property name="sqlSessionTemplate" ref="sqlSession" /> <!--也可直接注入SqlSessionFactory实例,二者都指定时,SqlSessionFactory失效 --> <!-- <property name="sqlSessionFactory" ref="sqlSessionFactory" /> --> </bean>
当然还有两种session配置了 就是:MapperFactoryBean和MapperScannerConfigurer:
这两种就不介绍了,当然了还有事务管理也没有说明了。