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註解實現  

相關文章
相關標籤/搜索