首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring + MyBatis 整合完整配置指南:從 XML 到註解驅動開發

     編輯:Java 綜合教學

前言

MyBatis (原 iBATIS) 作為半自動 ORM 框架,與 Spring 整合是企業級開發常見技術棧。本文系統梳理整合配置全流程,重點講解註解驅動開發模式與 SqlBuilder 動態 SQL 構建。

依賴引入

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.0.5</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.0.1</version>
</dependency>

MyBatis 全域配置 (configuration.xml)

僅保留 Settings 與 TypeAliases,其餘 (DataSource、Transaction 等) 交由 Spring 管理:

<configuration>
  <settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
    <setting name="multipleResultSetsEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>
    <setting name="useGeneratedKeys" value="true"/>
    <setting name="autoMappingBehavior" value="FULL"/>
    <setting name="defaultExecutorType" value="BATCH"/>
    <setting name="defaultStatementTimeout" value="25000"/>
  </settings>
  <typeAliases>
    <typeAlias alias="TestBean" type="com.wotao.taotao.persist.test.dataobject.TestBean"/>
  </typeAliases>
  <!-- 註解模式下可省略 mappers 配置 -->
</configuration>

Spring 整合核心配置

1. C3P0 資料源

<bean id="testDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="driverClass" value="${db.driver.class}"/>
  <property name="jdbcUrl" value="${db.url}"/>
  <property name="user" value="${db.username}"/>
  <property name="password" value="${db.password}"/>
  <property name="initialPoolSize" value="5"/>
  <property name="minPoolSize" value="5"/>
  <property name="maxPoolSize" value="20"/>
  <property name="maxStatements" value="100"/>
  <property name="maxIdleTime" value="3600"/>
  <property name="acquireIncrement" value="2"/>
  <property name="acquireRetryAttempts" value="10"/>
  <property name="acquireRetryDelay" value="600"/>
  <property name="checkoutTimeout" value="10000"/> <!-- 關鍵:防止資料庫響應慢導致誤判超時 -->
</bean>

2. SqlSessionFactory

<bean id="testSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="configLocation" value="classpath:configuration.xml"/>
  <property name="dataSource" ref="testDataSource"/>
</bean>

3. Mapper 接口掃描 (註解模式核心)

<bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="sqlSessionFactory" ref="testSqlSessionFactory"/>
  <property name="mapperInterface" value="com.wotao.taotao.persist.test.mapper.TestMapper"/>
</bean>

無需配置 SqlSessionTemplate,MapperFactoryBean 直接代理 Mapper 接口。

註解驅動 Mapper 開發

Mapper 接口定義

@CacheNamespace(size = 512)
public interface TestMapper {

    @SelectProvider(type = TestSqlProvider.class, method = "getSql")
    @Options(useCache = true, flushCache = false, timeout = 10000)
    @Results({
        @Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR),
        @Result(property = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR)
    })
    TestBean get(@Param("id") String id);

    @SelectProvider(type = TestSqlProvider.class, method = "getAllSql")
    @Options(useCache = true, flushCache = false, timeout = 10000)
    @Results({ ... })
    List<TestBean> getAll();

    @SelectProvider(type = TestSqlProvider.class, method = "getByTestTextSql")
    @Options(useCache = true, flushCache = false, timeout = 10000)
    @ResultMap("getByTestText")  // 複雜映射引用 XML resultMap
    List<TestBean> getByTestText(@Param("testText") String testText);

    @InsertProvider(type = TestSqlProvider.class, method = "insertSql")
    @Options(flushCache = true, timeout = 20000)
    void insert(@Param("testBean") TestBean testBean);

    @UpdateProvider(type = TestSqlProvider.class, method = "updateSql")
    @Options(flushCache = true, timeout = 20000)
    void update(@Param("testBean") TestBean testBean);

    @DeleteProvider(type = TestSqlProvider.class, method = "deleteSql")
    @Options(flushCache = true, timeout = 20000)
    void delete(@Param("id") String id);
}

關鍵註解解析

註解用途
@CacheNamespace命名空間級二級快取,size=512 條目
@SelectProvider指定 SQL 提供類/方法,分離 SQL 與介面
@Options查詢選項:快取、刷新、超時
@Results / @Result結果映射:欄位→屬性、主鍵標記、類型轉換
@ResultMap引用 XML 定義的 <resultMap>,支援嵌套/鑑別器
@Param參數命名,SQL 中用 #{paramName} 引用
@InsertProvider/@UpdateProvider/@DeleteProvider增刪改 SQL 提供者

XML ResultMap 範例 (配合 @ResultMap)

<mapper namespace="com.wotao.taotao.persist.test.mapper.TestMapper">
  <resultMap id="getByTestText" type="TestBean">
    <id property="id" column="test_id" javaType="string" jdbcType="VARCHAR"/>
    <result property="testText" column="test_text" javaType="string" jdbcType="VARCHAR"/>
  </resultMap>
</mapper>

注意:namespace 必須為 Mapper 接口全限定名,id 與 @ResultMap value 一致。

SQL Provider 動態構建 (SqlBuilder)

public class TestSqlProvider {
    private static final String TABLE_NAME = "test";

    public String getSql(Map<String, Object> params) {
        String uid = (String) params.get("id");
        BEGIN();
        SELECT("test_id, test_text");
        FROM(TABLE_NAME);
        if (uid != null) WHERE("test_id = #{id,javaType=string,jdbcType=VARCHAR}");
        return SQL();
    }

    public String getAllSql() {
        BEGIN(); SELECT("test_id, test_text"); FROM(TABLE_NAME); return SQL();
    }

    public String getByTestTextSql(Map<String, Object> params) {
        String tText = (String) params.get("testText");
        BEGIN(); SELECT("test_id, test_text"); FROM(TABLE_NAME);
        if (tText != null) WHERE("test_text like #{testText,javaType=string,jdbcType=VARCHAR}");
        return SQL();
    }

    public String insertSql() {
        BEGIN(); INSERT_INTO(TABLE_NAME);
        VALUES("test_id", "#{testBean.id,javaType=string,jdbcType=VARCHAR}");
        VALUES("test_text", "#{testBean.testText,javaType=string,jdbcType=VARCHAR}");
        return SQL();
    }

    public String updateSql() {
        BEGIN(); UPDATE(TABLE_NAME);
        SET("test_text = #{testBean.testText,javaType=string,jdbcType=VARCHAR}");
        WHERE("test_id = #{testBean.id,javaType=string,jdbcType=VARCHAR}");
        return SQL();
    }

    public String deleteSql() {
        BEGIN(); DELETE_FROM(TABLE_NAME);
        WHERE("test_id = #{id,javaType=string,jdbcType=VARCHAR}");
        return SQL();
    }
}

BEGIN() 清理線程局部變量,SELECT/FROM/WHERE/SET/VALUES 等靜態方法鏈式構建 SQL,SQL() 返回最終字串。支援 JOIN、GROUP_BY、ORDER_BY 等進階子句。

DAO 層注入使用

@Repository("testBaseDAO")
public class TestBaseDAO {
    private TestMapper testMapper;

    @Autowired
    public void setTestMapper(@Qualifier("testMapper") TestMapper testMapper) {
        this.testMapper = testMapper;
    }
    // 業務方法調用 testMapper.get(id) 等
}

總結

  1. Spring 管理 DataSource、SqlSessionFactory、事務;MyBatis 負責 SQL 映射
  2. 註解模式下,MapperFactoryBean 直接代理 Mapper 介面,無需 SqlSessionTemplate
  3. 複雜映射 (嵌套、鑑別器) 建議用 XML resultMap + @ResultMap 混合
  4. SqlBuilder 讓動態 SQL 保持類型安全與可讀性,避免字串拼接錯誤
  5. 參數命名 (@Param) 讓 SQL 參數引用更清晰,不依賴順序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved