mybatis+spring+struts2框架整合

jopen 8年前

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本
身,而是工厂类的getObject()返回的方法的结果。这种情况下,Spring将会在应用启动时为你创建SqlSessionFactory对象,

然后将它以SqlSessionFactory为名来存储。在Java中,相同的代码是:

SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();   SqlSessionFactory sessionFactory = factoryBean.getObject();

在一般的MyBatis-Spring用法中,你不需要直接使用SqlSessionFactoryBean或和其对

应的SqlSessionFactory。相反,session工厂将会被注入到MapperFactoryBean或其它扩
展了SqlSessionDaoSupport的DAO(也就是数据访问对象)中。

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>

4.2、SqlSessionSupport:

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:

这两种就不介绍了,当然了还有事务管理也没有说明了。


来自: http://blog.csdn.net//u011067360/article/details/17754291