mybatis的動態sql語句
㈠ MyBatis 動態sql where/if/choose/bind介紹
面對復雜的SQL拼接問題,MyBatis 動態SQL功能顯得尤為重要。它通過一系列如if, choose, when, otherwise, trim, where, set, foreach等標簽,實現了SQL語句的靈活構建,確保了准確性和開發效率的提升。
首先,where+if標簽用於處理多參數的條件判斷。例如,當第二個參數為空時,它會自動處理條件語句,避免了不必要的空值影響。在單參數傳遞時,它確保了SQL的完整性。
其次,where+choose標簽類似於Java的switch語句,允許根據給定的條件選擇執行特定的查詢條件,只需滿足其中一個條件即可,實現了查詢邏輯的靈活切換。
而在處理多個參數時,choose標簽會執行第一個滿足條件的部分,後續條件將被忽略,這與Java的短路邏輯類似。
最後,where+bind標簽則是綁定OGNL表達式的值到變數,特別適合在模糊查詢中,提供方便的變數引用,簡化了查詢語句的編寫。
總結起來,MyBatis的動態SQL提供了強大的條件控制和變數綁定功能,使得復雜的SQL構建變得直觀且易於管理,極大地提高了開發效率。
㈡ Mybatis 動態sql語句if標簽和where標簽結合巧妙使用
在Mybatis中,動態SQL的if標簽和where標簽可以巧妙地結合,以實現靈活的查詢條件。假設我們的需求是根據電話和名字查找用戶數據。
初始的SQL查詢可能看起來像這樣:
SELECT * FROM users WHERE mobile LIKE '%{mobile}' AND gender = #{gender}
在Mapper.xml文件中,配置的動態SQL如下:
<select id="getUserByPhoneName">
SELECT * FROM users
<choose>
<when test="gender != null">
AND gender = #{gender}
</when>
<otherwise>
-- 如果gender未傳,則不添加此條件
</otherwise>
</choose>
AND mobile LIKE #{mobile}
</select>
在代碼塊2-2中,我們對性別條件進行了改進,使用if標簽來判斷,僅當gender為0或1時執行查詢,代碼如下:
<if test="gender != null">
AND gender = #{gender}
</if>
如果要查詢所有用戶信息而不指定gender和username,可以修改代碼塊2-3,移除if標簽:
<!-- 移除if標簽 -->
AND mobile LIKE #{mobile}
總結,通過結合if標簽,我們可以靈活地根據傳入的參數動態調整SQL查詢條件。這在處理不同場景下的用戶查詢時顯得尤其有用。
㈢ Mybatis Plus是如何實現動態SQL語句的原理你懂嗎
Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具,那麼它是怎麼增強的呢?其實就是它已經封裝好了一些crud方法,開發就不需要再寫xml了,直接調用這些方法就行,就類似於JPA。
那麼這篇文章就來閱讀以下MP的具體實現,看看是怎樣實現這些增強的。
入口類:通過在入口類 #build方法中, 在應用啟動時, 將MyBatis plus(簡稱MP)自定義的動態配置xml文件注入到Mybatis中。
{publicSqlSessionFactorybuild(Configurationconfiguration){//...省略若干行if(globalConfig.isEnableSqlRunner()){newSqlRunnerInjector().inject(configuration);}//...省略若干行returnsqlSessionFactory;}}這里涉及到2個MP2個功能類
擴展繼承自Mybatis的MybatisConfiguration類: MP動態腳本構建,注冊,及其它邏輯判斷。
SqlRunnerInjector: MP默認插入一些動態方法的xml 腳本方法。
MybatisConfiguration類這里我們重點剖析MybatisConfiguration類,在MybatisConfiguration中,MP初始化了其自身的MybatisMapperRegistry,而MybatisMapperRegistry是MP載入自定義的SQL方法的注冊器。
MybatisConfiguration中很多方法是使用MybatisMapperRegistry進行重寫實現
其中有3個重載方法addMapper實現了注冊MP動態腳本的功能。
{/***Mapper注冊*/=newMybatisMapperRegistry(this);//..../***初始化調用*/publicMybatisConfiguration(){super();this.mapUnderscoreToCamelCase=true;languageRegistry.setDefaultDriverClass(MybatisXMLLanguageDriver.class);}/***MybatisPlus載入SQL順序:*<p>1、載入XML中的SQL</p>*<p>2、載入SqlProvider中的SQL</p>*<p>3、XmlSql與SqlProvider不能包含相同的SQL</p>*<p>調整後的SQL優先順序:XmlSql>sqlProvider>CurdSql</p>*/@(MappedStatementms){//...}//...省略若干行/***使用自己的MybatisMapperRegistry*/@Overridepublic<T>voidaddMapper(Class<T>type){mybatisMapperRegistry.addMapper(type);}//....省略若干行}在MybatisMapperRegistry中,MP將mybatis的MapperAnnotationBuilder替換為MP自己的
{@Overridepublic<T>voidaddMapper(Class<T>type){//...省略若干行parser=new(config,type);parser.parse();//...省略若干行}}在MybatisMapperRegistry類的addMapper方法中,真正進入到MP的核心類,這個類是MP實現動態腳本的關鍵類。
動態構造在MP的核心類的parser方法中,MP逐一遍歷要載入的Mapper類,載入的方法包括下面幾個
{@Overridepublicvoidparse(){//...省略若干行for(Methodmethod:type.getMethods()){/**for循環代碼,MP判斷method方法是否是@Select@Insert等mybatis註解方法**/parseStatement(method);InterceptorIgnoreHelper.initSqlParserInfoCache(cache,mapperName,method);SqlParserHelper.initSqlParserInfoCache(mapperName,method);}/**這2行代碼,MP注入默認的方法列表**/if(GlobalConfigUtils.isSupperMapperChildren(configuration,type)){GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant,type);}//...省略若干行}@(,Class<?>mapperClass){Class<?>modelClass=extractModelClass(mapperClass);//...省略若干行List<AbstractMethod>methodList=this.getMethodList(mapperClass);TableInfotableInfo=TableInfoHelper.initTableInfo(builderAssistant,modelClass);//循環注入自定義方法methodList.forEach(m->m.inject(builderAssistant,mapperClass,modelClass,tableInfo));mapperRegistryCache.add(className);}}{@OverridepublicList<AbstractMethod>getMethodList(Class<?>mapperClass){returnStream.of(newInsert(),//...省略若干行newSelectPage()).collect(toList());}}在中,MP真正將框架自定義的動態SQL語句注冊到Mybatis引擎中。而AbstractMethod則履行了具體方法的SQL語句構造。
具體的AbstractMethod實例類,構造具體的方法SQL語句以 SelectById 這個類為例說明下
/***根據ID查詢一條數據*/{@(Class<?>mapperClass,Class<?>modelClass,TableInfotableInfo){/**定義mybatisxmlmethodid,對應<id="xyz">**/SqlMethodsqlMethod=SqlMethod.SELECT_BY_ID;/**構造id對應的具體xml片段**/SqlSourcesqlSource=newRawSqlSource(configuration,String.format(sqlMethod.getSql(),sqlSelectColumns(tableInfo,false),tableInfo.getTableName(),tableInfo.getKeyColumn(),tableInfo.getKeyProperty(),tableInfo.getLogicDeleteSql(true,true)),Object.class);/**將xmlmethod方法添加到mybatis的MappedStatement中**/returnthis.(mapperClass,getMethod(sqlMethod),sqlSource,tableInfo);}}至此,MP完成了在啟動時載入自定義的方法xml配置的過程,後面的就是mybatis ${變數} #{變數}的動態替換和預編譯,已經進入mybatis自有功能。
總結一下MP總共改寫和替換了mybatis的十多個類,主要如下圖所示:
總體上來說,MP實現mybatis的增強,手段略顯繁瑣和不夠直觀,其實根據構造出自定義方法的xml文件,將其轉換為mybatis的Resource資源,可以只繼承重寫一個Mybatis類:SqlSessionFactoryBean 比如如下:
entsApplicationContextAware{privateResource[]mapperLocations;@(Resource...mapperLocations){super.setMapperLocations(mapperLocations);/**暫存使用mybatis原生定義的mapperxml文件路徑**/this.mapperLocations=mapperLocations;}/***{@inheritDoc}*/@()throwsException{=getBeanFactory();/**只需要通過將自定義的方法構造成xmlresource和原生定義的Resource一起注入到mybatis中即可,這樣就可以實現MP的自定義動態SQL和原生SQL的共生關系**/this.setMapperLocations(InjectMapper.getMapperResource(this.dbType,beanFactory,this.mapperLocations));super.afterPropertiesSet();}}在這邊文章中,簡單介紹了MP實現動態語句的實現過程,並且給出一個可能的更便捷方法。
來源:juejin.cn/post/6883081187103866894
㈣ MyBatis動態SQL標簽的用法
MyBatis動態SQL標簽的用法主要包括以下幾個核心元素:
if標簽:
- 用途:用於在SQL語句中添加條件判斷。
- 功能:根據條件表達式的真假,決定是否包含某段SQL代碼。
choose標簽:
- 用途:類似於Java中的switch語句,用於在多個條件中選擇一個執行。
- 功能:包含一個或多個when標簽和一個可選的otherwise標簽,當某個when標簽的條件滿足時,執行對應的SQL代碼。
where標簽:
- 用途:用於自動處理SQL中的where條件語句。
- 功能:能夠智能地添加條件,同時自動處理邏輯和空格,避免生成語法錯誤的SQL。
set標簽:
- 用途:在更新操作中,用於添加或修改條件。
- 功能:與where標簽類似,能夠智能地處理更新語句中的set部分,自動添加逗號等符號。
foreach標簽:
- 用途:用於處理集合數據,循環執行SQL語句。
- 功能:能夠遍歷集合中的元素,生成相應的SQL代碼,常用於處理IN查詢或批量插入/更新操作。
trim標簽:
- 用途:允許在SQL內容前後添加前綴和後綴,或忽略某些特定部分。
- 功能:提供了強大的格式化和定製功能,通過prefix、suffix、prefixOverrides和suffixOverrides等屬性來控制SQL代碼的格式。
這些動態SQL標簽為編寫高效且靈活的SQL提供了強大工具,使得在編寫SQL時能夠更加智能化和靈活地處理復雜邏輯和數據處理需求。
㈤ Mybatis Plus 實現動態SQL語句的原理
Mybatis Plus 實現動態SQL語句的原理主要基於以下幾個關鍵點:
**1. 入口類與自定義配置 的build方法:在應用啟動時,Mybatis Plus通過的build方法動態注入其自定義配置XML文件到Mybatis中。
**2. 關鍵功能類 MybatisConfiguration:擴展自Mybatis的MybatisConfiguration類主要負責動態腳本的構建、注冊和邏輯判斷。它初始化了MybatisMapperRegistry,該注冊器負責載入自定義SQL方法。 SqlRunnerInjector:負責添加Mybatis Plus特有的動態方法的XML腳本。
**3. 核心解析類 :這是Mybatis Plus的核心類,它在解析Mapper類時動態構造SQL語句。例如,對於SelectById這樣的操作,Mybatis MapperAnnotationBuilder會根據註解或配置動態生成相應的SQL語句。
**4. 重寫與替換 Mybatis Plus對Mybatis的十多個類進行了重寫和替換,包括Mybatis的MapperAnnotationBuilder和處理動態SQL的邏輯。這種重寫和替換使得Mybatis Plus能夠在Mybatis的基礎上實現更高級的功能,如無需XML配置即可進行CRUD操作。
**5. 配置與擴展 通過一系列的配置和擴展,Mybatis Plus實現了無XML的CRUD操作,極大地提升了開發效率。雖然實現過程相對繁瑣,但最終的結果是開發者可以更加便捷地使用Mybatis進行資料庫操作。
綜上所述,Mybatis Plus通過入口類的自定義配置、關鍵功能類的擴展、核心解析類的動態構造、對Mybatis類的重寫與替換以及一系列的配置與擴展,實現了動態SQL語句的生成與注冊。