MyBatis Spring 最佳实践

MyBatis Spring 最佳实践
  1. mybatis与spring整合
  2. 注解
  3. 事务处理
  4. 批量操做(插入、更新、删除)
  5. 多表查询

MyBatis与Spring整合

前提:

已经完成spring的简单配置 html

. 采用数据映射器(MapperFactoryBean) java

spring配置 git

<!-- 建立SqlSessionFactory,同时指定数据源-->  
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">   
     <property name="dataSource" ref="dataSource" />   
 </bean>   

 <!--建立数据映射器,数据映射器必须为接口-->  
 <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">   
     <property name="mapperInterface" value="com.xxt.ibatis.dbcp.dao.UserMapper" />   
     <property name="sqlSessionFactory" ref="sqlSessionFactory" />   
 </bean>

java代码 github

package com.xxt.ibatis.dbcp.dao.UserMapper;
public interface UserMapper {  
  @Select("SELECT * FROM user WHERE id = #{userId}")   
  User getUser(@Param("userId") long id);   
}

此种方式配置,省去了xml的配置,全部的sql语句都是经过注解的方式来配置,对于简单的数据库操做比较简单,此种配置是不二直选。注意此种配置须要写配置文件,若是想配置DAO全注解,此种方式没法完成。 spring

. SqlSessionTemplate sql

spring配置 数据库

<!-- 建立SqlSessionFactory,同时指定数据源-->  
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">   
    <property name="dataSource" ref="dataSource" />   
    <!-- 指定sqlMapConfig总配置文件,订制的environment在spring容器中不在生效-->  
    <property  name="configLocation"  value="classpath:sqlMapConfig.xml"/>  
    <!--指定实体类映射文件,能够指定同时指定某一包以及子包下面的全部配置文件,mapperLocations和configLocation有一个便可,当须要为实体类指定别名时,可指定configLocation属性,再在mybatis总配置文件中采用mapper引入实体类映射文件 -->  
    <!- - 
    <property  name="mapperLocations"  value="classpath*:com/xxt/ibatis/dbcp*.xml"/>  
    -->         
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
  <constructor-arg index="1" value="BATCH" />
</bean>

sqlMapConfig.xml express

<configuration>
    <typeAliases>  
        <typeAlias type="com.xxt.ibatis.dbcp.domain.User" alias="User" />
    </typeAliases>
    <mappers>  
        <mapper resource="com/xxt/ibatis/dbcp/domain/user.map.xml" />
    </mappers>  
</configuration>

user.map.xml 网络

<mapper namespace="com.xxt.ibatis.dbcp.domain.User">  
    <resultMap type="User" id="userMap">  
        <id property="id" column="id" />  
        <result property="name" column="name" />  
        <result property="password" column="password" />  
        <result property="createTime" column="createtime" />  
     </resultMap>  
     <select id="getUser" parameterType="User" resultMap="userMap">  
       select * from user where id = #{id}  
    </select>  
<mapper/>

java代码 mybatis

public class UserDaoImpl implements  UserDao  {  
    public SqlSessionTemplate sqlSession;  
    public User getUserById(User user) {  
      return (User)sqlSession.selectOne("com.xxt.ibatis.dbcp.domain.User.getUser", user);  
    }  
   public void setSqlSession(SqlSessionTemplate sqlSession) {  
      this.sqlSession = sqlSession;  
   }
 }

此中方式的配置,看起来比较繁琐,既要写spring的配置文件,又要写sqlmapper配置文件,还须要写java代码。可是此种配置,也就是基于 SqlSessionTemplate 的操做,能够使用BATCH的方式操做数据库。

. SqlSessionDaoSupport

spring配置

<!-- 建立SqlSessionFactory,同时指定数据源-->  
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">   
    <property name="dataSource" ref="dataSource" />   
    <!-- 指定sqlMapConfig总配置文件,订制的environment在spring容器中不在生效-->  
    <property  name="configLocation"  value="classpath:sqlMapConfig.xml"/>  
    <!--指定实体类映射文件,能够指定同时指定某一包以及子包下面的全部配置文件,mapperLocations和configLocation有一个便可,当须要为实体类指定别名时,可指定configLocation属性,再在mybatis总配置文件中采用mapper引入实体类映射文件 -->  
    <!- - 
    <property  name="mapperLocations"  value="classpath*:com/xxt/ibatis/dbcp*.xml"/>  
    -->         
</bean>

<bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserMapperImpl">      <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

user.map.xml

<mapper namespace="com.xxt.ibatis.dbcp.domain.User">  
    <resultMap type="User" id="userMap">  
        <id property="id" column="id" />  
        <result property="name" column="name" />  
        <result property="password" column="password" />  
        <result property="createTime" column="createtime" />  
     </resultMap>  
     <select id="getUser" parameterType="User" resultMap="userMap">  
       select * from user where id = #{id}  
    </select>  
<mapper/>

java代码

public class UserMapperDaoImpl extends SqlSessionDaoSupport implements  UserMapper { 
    public User getUser(String userId) {
        return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId); 
    }
}

参考:mybatis-spring官网文档、摘自网络

最佳实践

  1. 多有的操做,最好基于注解方式的配置。包括@Controller、@Service、@Repository.采用注解+xml配置的方式实现,对于复杂的配置采用XML方式。
  2. 单表操做,对数据量不是很大,采用注解方式实现。
  3. 多表操做,大数据量批次操做,采用SqlSessionTemplate方式操做。
  4. 事务控制,经过spring实现。

注解

  1. 自动扫描注解

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         <property name="sqlSessionFactory" ref="sqlSessionFactory" />
         <property name="basePackage" value="org.cn.zhaozhx.weather.dao" />
     </bean>
  2. DAO接口

    @Repository

  3. Sql语句

    详见《MyBatis-3-User-Guide_zh_zlz.pdf》

事务处理

事务处理经过spring控制。

<!-- 事务管理器 -->
<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="druid" />
</bean>

具体的实现方式能够经过AOP或者拦截器方式实现

spring mvc mybatis 基于注解方式事务处理注意事项
  1. spring 自动扫描注解的时候,不去扫描@Controller

    <context:component-scan base-package ="org.cn.zhaozhx">
         <context:exclude-filter type ="annotation" expression= "org.springframework.stereotype.Controller" />
     </context:component-scan >
  2. spring mvc 自动扫描注解的时候,不去扫描@Service

    <context:component-scan base-package= "org.cn.zhaozhx">
         <context:exclude-filter type ="annotation" expression= "org.springframework.stereotype.Service" />
     </context:component-scan >

    参考:http://blog.sina.com.cn/s/blog_5ddc071f0100uf7x.html。尤为是这段话:

    Spring MVC启动时的配置文件,包含组件扫描、url映射以及设置freemarker参数,让spring不扫描带有@Service注解的类。为何要这样设置?由于servlet-context.xml与service-context.xml不是同时加载,若是不进行这样的设置,那么,spring就会将全部带@Service注解的类都扫描到容器中,等到加载service-context.xml的时候,会由于容器已经存在Service类,使得cglib将不对Service进行代理,直接致使的结果就是在service-context中的事务配置不起做用,发生异常时,没法对数据进行回滚。

批量操做(插入、更新、删除)

  1. 使用MyBatis API(不推荐)
  2. SqlSessionTemplate
  3. MyBatisPagingItemReade

多表查询

详见 MyBatis_3_User_Guide_zh_nl.pdf

MyBatis 返回以某列做为KEY,当前一条记录为VALUE的MAP

经过 @MapKey注解实现  

相关文章
相关标签/搜索