Mybatis系列之六 MapperStatement 字典篇

之前我們分析了Mybatis初始做的工作,以及Mapper執(zhí)行命令的部分原理,接下來(lái)我們就準(zhǔn)備開始Mybatis到底是如何去分析執(zhí)行SQL的。而這個(gè)過程十分依賴MappedStatement這個(gè)類,所以我們繼續(xù)分析之前先把這個(gè)類簡(jiǎn)單介紹一下,它主要是Mybatis初始化時(shí)通過解析mapper對(duì)應(yīng)的XML文件來(lái)生成,它的每個(gè)屬性基本上都能對(duì)上XML中的某一個(gè)配置。

demo

    <select id="count" resultType="int">
        SELECT
        count(1)
        FROM
        <include refid="table"/>
    </select>

    <select id="queryPage" parameterType="cn.com.bsfit.model.so.EmployeeSO" resultMap="baseResultMap">
        SELECT
        <include refid="base_columns"/>
        FROM
        <include refid="table"/>
        limit #{offset},#{limit}
    </select>

MappedStatement 字段解析

public final class MappedStatement {
  // Mapper來(lái)源,當(dāng)前Statement是哪個(gè)XML文件解析出來(lái)的。
  // 例如:file [/home/hwb/git/study/studymybatis/target/classes/cn/com/bsfit/mapper/PersonMapper.xml]
  private String resource;
  // 全局的配置
  private Configuration configuration;
  // sql id , 如例子中的 count
  private String id;
  // fetchSize, ResultSet.next()取數(shù)據(jù)時(shí)客戶端緩存行數(shù)大小
  private Integer fetchSize;
  // sql超時(shí)時(shí)間
  private Integer timeout;
  // sql的類型,INSERT | DELETE | UPDATE | SELECT
  private StatementType statementType;
  // ResultSet的ResultSetType
  private ResultSetType resultSetType;
  // 解析了mybatis語(yǔ)法后帶占位符的Sql,例如: SELECT id, userId, userName, nickName, gender, mobilePhone, miliao, email FROM employee limit ?,?
  private SqlSource sqlSource;
  // mybatis 2級(jí)緩存
  private Cache cache;
  // 請(qǐng)求參數(shù)類型
  private ParameterMap parameterMap;
  // 返回結(jié)果類型
  private List<ResultMap> resultMaps;
  // 是否需要刷新緩存
  private boolean flushCacheRequired;
  // 是否使用緩存
  private boolean useCache;
  // 這個(gè)設(shè)置僅針對(duì)嵌套結(jié)果 select 語(yǔ)句適用:如果為 true,就是假設(shè)包含了嵌套結(jié)果集或是分組了,這樣的話當(dāng)返回一個(gè)主結(jié)果行的時(shí)候,就不會(huì)發(fā)生有對(duì)前面結(jié)果集的引用的情況。這就使得在獲取嵌套的結(jié)果集的時(shí)候不至于導(dǎo)致內(nèi)存不夠用。默認(rèn)值:false。
  private boolean resultOrdered;
  // SQL類型 UNKNOWN, INSERT, UPDATE, DELETE, SELECT;
  private SqlCommandType sqlCommandType;
  // 主鍵生成器
  private KeyGenerator keyGenerator;
  // 對(duì)應(yīng)XML中的keyProperty selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱列表。
  private String[] keyProperties;
  // keyColumn  匹配屬性的返回結(jié)果集中的列名稱。如果希望得到多個(gè)生成的列,也可以是逗號(hào)分隔的屬性名稱列表。
  private String[] keyColumns;
  // 對(duì)應(yīng)的ResultMap對(duì)用有內(nèi)置的ResultMap
  private boolean hasNestedResultMaps;
  // 如果配置了數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)(databaseIdProvider),MyBatis 會(huì)加載所有的不帶 databaseId 或匹配當(dāng)前 databaseId 的語(yǔ)句;如果帶或者不帶的語(yǔ)句都有,則不帶的會(huì)被忽略。
  // 在使用多個(gè)數(shù)據(jù)庫(kù)的情況下使用
  private String databaseId;
  // 內(nèi)部日志類
  private Log statementLog;
  // 默認(rèn)是XMLLanguageDriver
  private LanguageDriver lang;
  // 這個(gè)設(shè)置僅對(duì)多結(jié)果集的情況適用。它將列出語(yǔ)句執(zhí)行后返回的結(jié)果集并給每個(gè)結(jié)果集一個(gè)名稱,名稱是逗號(hào)分隔的
  private String[] resultSets;

}

簡(jiǎn)單介紹一下它的解析邏輯

首先是在SqlSessionFactoryBean中創(chuàng)建SqlSessionFactory時(shí),通過把配置好的XML資源路徑傳遞給XMLMapperBuilder,由XMLMapperBuilder去解析XML,然后再交由XMLStatementBuilder類去具體解析某一個(gè)SQL對(duì)應(yīng)的配置,最后由MapperBuilderAssistant幫忙注冊(cè)到configuration中的Map<String, MappedStatement> mappedStatements中。

下面的圖片是Mybatis各種Builder類,它們都繼承了BaseBuilder,有興趣的同學(xué)可以自行了解下。


Builder.png

ok,今天到這里了,接下來(lái)就要開始分析Mybaits是如何執(zhí)行SQL的了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容