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

MyBatis 進階:擴展 SqlSessionFactoryBean 實現 SqlMapper 配置文件 XSD 模式驗證

     編輯:Java 綜合教學

MyBatis 進階:擴展 SqlSessionFactoryBean 實現 SqlMapper 配置文件 XSD 模式驗證

背景

MyBatis 預設使用 DTD 驗證 Mapper XML 文件。為獲得更強的型別約束、自動完成與驗證能力,需擴展以支援 XSD (XML Schema Definition) 驗證模式。

一、覆寫 doParseSqlMapperResource() 方法,實現雙模式兼容

建立 SchemaSqlSessionFactoryBean 繼承重構後的 SqlSessionFactoryBean,覆寫解析入口方法,利用 Spring 的 XmlValidationModeDetector 偵測驗證模式:

package org.dysd.dao.mybatis.schema;

import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.session.Configuration;
import org.springframework.core.NestedIOException;
import org.springframework.core.io.Resource;
import org.springframework.util.xml.XmlValidationModeDetector;

public class SchemaSqlSessionFactoryBean extends SqlSessionFactoryBean {

    @Override
    protected void doParseSqlMapperResource(Configuration configuration, Resource mapperLocation) throws NestedIOException {
        int mode = detectValidationMode(mapperLocation);
        if (mode == XmlValidationModeDetector.VALIDATION_DTD) {
            // DTD 模式:使用 MyBatis 官方解析
            super.doParseSqlMapperResource(configuration, mapperLocation);
        } else {
            // XSD 模式:自定義解析
            try {
                this.doParseSqlMapperResourceWithSchema(configuration, mapperLocation);
            } catch (Exception e) {
                throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
            } finally {
                ErrorContext.instance().reset();
            }
        }
    }

    protected void doParseSqlMapperResourceWithSchema(Configuration configuration, Resource mapperLocation) {
        // TODO: 實現基於 XSD 的解析邏輯
    }

    private int detectValidationMode(Resource mapperLocation) throws NestedIOException {
        int mode = -1;
        try {
            XmlValidationModeDetector detector = new XmlValidationModeDetector();
            mode = detector.detectValidationMode(mapperLocation.getInputStream());
        } catch (Exception e) {
            throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
            ErrorContext.instance().reset();
        }
        return mode;
    }
}

關鍵點: XmlValidationModeDetector 逐行讀取 XML 前序內容,發現 DOCTYPE 宣告則判定為 DTD 模式,否則預設為 XSD 模式。

二、編寫 SqlMapper 專用 XSD Schema 文件

  1. 工具轉換: 使用 XML 工具(如 Oxygen、IntelliJ IDEA)將 MyBatis 官方 mybatis-3-mapper.dtd 轉換為初始 XSD。
  2. 三層級元素結構設計:
    • 根元素:<mapper>,屬性 namespace(邏輯分類,非 XML 命名空間)。
    • 一級子元素:cache、cache-ref、resultMap、parameterMap、sql、insert、update、delete、select —— 統稱「語句級」元素。
    • 腳本級元素:include、trim、where、set、foreach、choose、if —— 用於動態 SQL 腳本構建。
  3. 關鍵修改項目:
    • 添加目標命名空間:targetNamespace="https://dysd.org/schema/sqlmapper"
    • 將一級元素包裝為 <xsd:group name="statementGroup"> 便於複用。
    • 修改 mapper 元素允許出現其他命名空間元素(<xsd:any namespace="##other" processContents="lax"/>)。
    • 將動態腳本元素包裝為 dynaScriptGroup,並允許擴展。
    • 在 <select> 等語句元素中使用 dynaScriptGroup 替換原有動態元素序列。
    • 將列舉型屬性(如 statementType、parameterMode、jdbcType、javaType)定義為 xsd:simpleType 限制枚舉值。
<xsd:simpleType name="statementType">
  <xsd:restriction base="xsd:token">
    <xsd:enumeration value="STATEMENT"/>
    <xsd:enumeration value="PREPARED"/>
    <xsd:enumeration value="CALLABLE"/>
  </xsd:restriction>
</xsd:simpleType>

後續規劃

完成 XSD 文件後,需在 doParseSqlMapperResourceWithSchema 中實現基於 XSD 的解析邏輯(使用 JAXP 驗證並轉換為 Configuration 物件),並註冊自定義命名空間處理器以支援擴展元素。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved