1. 程式人生 > >MyBatis原始碼解析 ---- MyBatis動態SQL底層原理分析

MyBatis原始碼解析 ---- MyBatis動態SQL底層原理分析

轉自 http://format-blog-image.qiniudn.com/dynamicsql2.png


前言

廢話不多說,直接進入文章。
我們在使用mybatis的時候,會在xml中編寫sql語句。
比如這段動態sql程式碼:

123456789101112131415<update id="update" parameterType="org.format.dynamicproxy.mybatis.bean.User">UPDATE users<trim prefix="SET" prefixOverrides=","><if test="name != null and name != ''"
>name = #{name}</if><if test="age != null and age != ''">, age = #{age}</if><if test="birthday != null and birthday != ''">, birthday = #{birthday}</if></trim>where id = ${id}</update>

mybatis底層是如何構造這段sql的?
這方面的知識網上資料不多,於是就寫了這麼一篇文章。
下面帶著這個疑問,我們一步一步分析。

介紹MyBatis中一些關於動態SQL的介面和類

SqlNode介面,簡單理解就是xml中的每個標籤,比如上述sql的update,trim,if標籤:

123public interface SqlNode {boolean apply(DynamicContext context);}

SqlSource Sql源介面,代表從xml檔案或註解對映的sql內容,主要就是用於建立BoundSql,有實現類DynamicSqlSource(動態Sql源),StaticSqlSource(靜態Sql源)等:

123public interface SqlSource {BoundSql getBoundSql(Object parameterObject);
}

BoundSql類,封裝mybatis最終產生sql的類,包括sql語句,引數,引數源資料等引數:

XNode,一個Dom API中的Node介面的擴充套件類。

BaseBuilder介面及其實現類(屬性,方法省略了,大家有興趣的自己看),這些Builder的作用就是用於構造sql:

下面我們簡單分析下其中4個Builder:

1 XMLConfigBuilder

解析mybatis中configLocation屬性中的全域性xml檔案,內部會使用XMLMapperBuilder解析各個xml檔案。

2 XMLMapperBuilder

遍歷mybatis中mapperLocations屬性中的xml檔案中每個節點的Builder,比如user.xml,內部會使用XMLStatementBuilder處理xml中的每個節點。

3 XMLStatementBuilder

解析xml檔案中各個節點,比如select,insert,update,delete節點,內部會使用XMLScriptBuilder處理節點的sql部分,遍歷產生的資料會丟到Configuration的mappedStatements中。

4 XMLScriptBuilder

解析xml中各個節點sql部分的Builder。

LanguageDriver介面及其實現類(屬性,方法省略了,大家有興趣的自己看),該介面主要的作用就是構造sql:

簡單分析下XMLLanguageDriver(處理xml中的sql,RawLanguageDriver處理靜態sql):

XMLLanguageDriver內部會使用XMLScriptBuilder解析xml中的sql部分。

ok, 大部分比較重要的類我們都已經介紹了,下面原始碼分析走起。

原始碼分析走起

Spring與Mybatis整合的時候需要配置SqlSessionFactoryBean,該配置會加入資料來源和mybatis xml配置檔案路徑等資訊:

12345<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatisConfig.xml"/><property name="mapperLocations" value="classpath*:org/format/dao/*.xml"/></bean>

我們就分析這一段配置背後的細節:

SqlSessionFactoryBean實現了Spring的InitializingBean介面,InitializingBean介面的afterPropertiesSet方法中會呼叫buildSqlSessionFactory方法

buildSqlSessionFactory方法內部會使用XMLConfigBuilder解析屬性configLocation中配置的路徑,還會使用XMLMapperBuilder屬性解析mapperLocations屬性中的各個xml檔案。

部分原始碼如下:

由於XMLConfigBuilder內部也是使用XMLMapperBuilder,我們就看看XMLMapperBuilder的解析細節。

我們關注一下,增刪改查節點的解析。

XMLStatementBuilder的解析:

預設會使用XMLLanguageDriver建立SqlSource(Configuration建構函式中設定)。

XMLLanguageDriver建立SqlSource:

XMLScriptBuilder解析sql:

得到SqlSource之後,會放到Configuration中,有了SqlSource,就能拿BoundSql了,BoundSql可以得到最終的sql。

例項分析

我以以下xml的解析大概說下parseDynamicTags的解析過程:

123456789101112131415<update id="update"

相關推薦

MyBatis原始碼解析 ---- MyBatis動態SQL底層原理分析

轉自 http://format-blog-image.qiniudn.com/dynamicsql2.png前言廢話不多說,直接進入文章。我們在使用mybatis的時候,會在xml中編寫sql語句。比如這段動態sql程式碼:123456789101112131415<

Spring4.x原始碼解析:IOC容器底層原理解析

引包 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans&

mybatis原始碼解析(六)-配合spring-tx實現事務的原理

spring-tx關鍵物件 物件包含關係 TransactionAspectSupport.TransactionInfo包含TransactionStatus物件,TransactionStatus物件包含DataSourceTransacti

Mybatis原始碼解析 —— Sql解析詳解

引言 Mybatis框架極大地簡化了ORM,讓使用者自定義sql語句,再將查詢結果對映到Java類中,其中很關鍵的一部分就是,將使用者寫的sql語句(以xml或者註解形式)解析成資料庫可執行的sql語句。 本文將會介紹這整個的解析過程。

Mybatis中的update動態SQL語句 <trim></trim> 用法

color 單獨 null 多個 ride 逗號 myba 不用 log Mybatis Mapper中文件中 update時,需要set設置多個字段,有時逗號處理時,會報錯誤,所以會使用到<trim></trim> 使用trim就是為了刪掉最後

mybatis註解開發,動態sql

sele sel myba 開始 xls inorder from all nbsp 在利用mybatis註解開始時,如果沒有用到動態sql時,可以直接寫 @Select("select * from order") List<XlSubOrder> getA

Spring Boot MyBatis升級篇-註解-動態SQL(if test)-方案二:@Provider(8)

指定 ins pro builder except uil test 就是 class 1)動態語言註解(2)@Provider使用思路(3)@SelectProvider小試牛刀(4)@SelectProvider初露鋒芒(5)@SelectProvider過關斬將(6)

Java框架-mybatis連線池、動態sql和多表查詢

1. mybatis連線池 通過SqlMapConfig.xml設定dataSource type實現連線池的配置 1.1 dataSource標籤type屬性值含義 type=”POOLED”: MyBatis 會建立 PooledDataSource 例項

MyBatis原始碼解析之日誌記錄

一 .概述 MyBatis沒有提供日誌的實現類,需要接入第三方的日誌元件,但第三方日誌元件都有各自的Log級別,且各不相同,但MyBatis統一提供了trace、debug、warn、error四個級別; 自動掃描日誌實現,並且第三方日誌外掛載入優先順序如下:slf4J → commonsLoging →

【學習轉載】MyBatis原始碼解析——日誌記錄

宣告:轉載自前輩:開心的魚a1 一 .概述 MyBatis沒有提供日誌的實現類,需要接入第三方的日誌元件,但第三方日誌元件都有各自的Log級別,且各不相同,但MyBatis統一提供了trace、debug、warn、error四個級別; 自動掃描日誌實現,並且第三方日誌外掛載入優先順序如下:sl

MyBatis原始碼解析之資料來源(含資料庫連線池簡析)

一.概述: 常見的資料來源元件都實現了javax.sql.DataSource介面; MyBatis不但要能整合第三方的資料來源元件,自身也提供了資料來源的實現; 一般情況下,資料來源的初始化過程引數較多,比較複雜; 二.設計模式: 為什麼要使用工廠模式     資料來

一起來學大資料|Mybatis之如魚得水的動態SQL,百樣玲瓏?

  昨天,我們就學習了mybatis的 一下相關的知識,文章開頭我們級提到它可以解決SQL的硬編碼問題,但是根據昨天的文章,我們並沒有看出mybatis的優勢。今天我們來使用mybatis中的動態sql來解決我們仍有的困惑。 動態 SQL 在mybatis框架中,動態

Mybatis原始碼解析Mybatis初始化過程

一、搭建一個簡單的Mybatis工程 為了瞭解Mybatis的初始化過程,這裡需要搭建一個簡單的Mybatis工程操作資料庫,工程結構如下: 一個UserBean.java private int id; private String user

mybatis原始碼-解析配置檔案(三)之配置檔案Configuration解析(超詳細, 值得收藏)

1. 簡介 1.1 系列內容 本系列文章講解的是mybatis解析配置檔案內部的邏輯, 即 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); SqlSessionFact

mybatis原始碼-解析配置檔案(二)之解析的流程

1. 簡介 在之前的文章《mybatis 初步使用(IDEA的Maven專案, 超詳細)》中, 講解了mybatis的初步使用, 並總結了以下mybatis的執行流程: 通過 Resources 工具類讀取 mybatis-config.xml,

mybatis原始碼-解析配置檔案(四)之配置檔案Mapper解析

其中, mappers作為configuration節點的一部分配置, 在本文章中, 我們講解解析mappers節點, 即 xxxMapper.xml 檔案的解析。 1 解析入口 在解析 mybatis-config.xml 時, 會進行解析 xxxMapper.xml 的檔案。 在圖示流程的 XMLCo

mybatis原始碼-解析配置檔案(四-1)之配置檔案Mapper解析(cache)

1. 簡介 本文章主要講解的是, xxxMapper.xml 檔案中, cache 節點的原始碼。 2. 解析 XMLMapperBuilder.cacheElement() 方法主要負責解析 <cache> private void cacheElement(XNode context)

<MyBatis>入門六 動態sql

package org.maple.mapper; import org.apache.ibatis.annotations.Param; import org.maple.pojo.Employee; import java.util.List; import java.util.Map; /*

mybatis原始碼解析第一課-mybatis原始碼匯入idea執行

從本篇部落格開始,進入mybatis的原始碼學習,本篇部落格主要是講解mybatis原始碼的下載,並將原始碼匯入到idea,可以用來除錯; 一、下載mybatis原始碼 版本:mybatis-3-mybatis-3.4.6.zip,下載地址:https://gi

Mybatis連線池丶動態sql丶抽取sql語句

當實體類的屬性(uid)與資料庫的欄位(id)不一致的時候 對於增刪改: 只需在傳入引數後的佔位符中把對應的屬性傳遞進去就行 對於查詢: 1. 可以通過資料庫的別名來解決 select id as uid from user 2. 可以使用r