Mybatis動(dòng)態(tài)SQL的實(shí)現(xiàn)示例
場(chǎng)景
在實(shí)際應(yīng)用開(kāi)發(fā)過(guò)程中,我們往往需要寫(xiě)復(fù)雜的 SQL 語(yǔ)句,需要拼接,而拼接SQL語(yǔ)句又稍微不注意,由于引號(hào),空格等缺失可能都會(huì)導(dǎo)致錯(cuò)誤。
Mybatis提供了動(dòng)態(tài)SQL,也就是可以根據(jù)用戶提供的參數(shù),動(dòng)態(tài)決定查詢語(yǔ)句依賴的查詢條件或SQL語(yǔ)句的內(nèi)容。
動(dòng)態(tài)SQL標(biāo)簽
if 和 where 標(biāo)簽
<!--動(dòng)態(tài)Sql : where / if--> <select id="dynamicSql" resultType="com.lks.domain.User"> select <include refid="tableAllkey"/> from users <where> <if test="id != null and id != 0"> AND id = #{id} </if> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="county != null and county != ''"> AND county = #{county} </if> </where> </select>
一般開(kāi)發(fā)列表業(yè)務(wù)的查詢條件時(shí),如果有多個(gè)查詢條件,通常會(huì)使用 標(biāo)簽來(lái)進(jìn)行控制。 標(biāo)簽可以自動(dòng)的將第一個(gè)條件前面的邏輯運(yùn)算符 (or ,and) 去掉,正如代碼中寫(xiě)的,id 查詢條件前面是有“and”關(guān)鍵字的,但是在打印出來(lái)的 SQL 中卻沒(méi)有,這就是 的作用。打印SQL語(yǔ)句的使用可以在mybatis-config文件中添加setting標(biāo)簽:
<settings> <!-- 打印查詢語(yǔ)句 --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings>
choose、when、otherwise 標(biāo)簽
這三個(gè)標(biāo)簽需要組合在一起使用,類似于 Java 中的 switch、case、default。只有一個(gè)條件生效,也就是只執(zhí)行滿足的條件 when,沒(méi)有滿足的條件就執(zhí)行 otherwise,表示默認(rèn)條件。
<!--動(dòng)態(tài)Sql: choose、when、otherwise 標(biāo)簽--> <select id="dynamicSql2" resultType="com.lks.domain.User"> select * from users <where> <choose> <when test="name != null and name != ''"> AND name = #{name} </when> <when test="county != null and county != ''"> AND county = #{county} </when> <otherwise> AND id = #{id} </otherwise> </choose> </where> </select>
在測(cè)試類中,即使同時(shí)添加name和county的值,最終的sql也只會(huì)添加第一個(gè)屬性值。
set 標(biāo)簽
使用set標(biāo)簽可以將動(dòng)態(tài)的配置 SET 關(guān)鍵字,并剔除追加到條件末尾的任何不相關(guān)的逗號(hào)。使用 if+set 標(biāo)簽修改后,在進(jìn)行表單更新的操作中,哪個(gè)字段中有值才去更新,如果某項(xiàng)為 null 則不進(jìn)行更新,而是保持?jǐn)?shù)據(jù)庫(kù)原值。
<!--動(dòng)態(tài)Sql: set 標(biāo)簽--> <update id="updateSet" parameterType="com.lks.domain.User"> update users <set> <if test="name != null and name != ''"> name = #{name}, </if> <if test="county != null and county != ''"> county = #{county}, </if> </set> where id = #{id} </update>
trim 標(biāo)簽
trim 是一個(gè)格式化標(biāo)簽,可以完成< set > 或者是 < where > 標(biāo)記的功能。主要有4個(gè)參數(shù):
① prefix:前綴
② prefixOverrides:去掉第一個(gè)and或者是or
③ suffix:后綴
④ suffixOverrides:去掉最后一個(gè)逗號(hào),也可以是其他的標(biāo)記
<!--動(dòng)態(tài)Sql: trim 標(biāo)簽--> <select id="dynamicSqlTrim" resultType="com.lks.domain.User"> select * from users <trim prefix="where" suffix="order by age" prefixOverrides="and | or" suffixOverrides=","> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="county != null and county != ''"> AND county = #{county} </if> </trim> </select>
foreach 標(biāo)簽
foreach標(biāo)簽主要有以下參數(shù):
item :循環(huán)體中的具體對(duì)象。支持屬性的點(diǎn)路徑訪問(wèn),如item.age,item.info.details,在list和數(shù)組中是其中的對(duì)象,在map中是value。
index :在list和數(shù)組中,index是元素的序號(hào),在map中,index是元素的key,該參數(shù)可選。
open :表示該語(yǔ)句以什么開(kāi)始
close :表示該語(yǔ)句以什么結(jié)束
separator :表示元素之間的分隔符,例如在in()的時(shí)候,separator=","會(huì)自動(dòng)在元素中間用“,“隔開(kāi),避免手動(dòng)輸入逗號(hào)導(dǎo)致sql錯(cuò)誤,如in(1,2,)這樣。該參數(shù)可選。
list批量插入
<!--動(dòng)態(tài)Sql: foreach標(biāo)簽, 批量插入--> <insert id="dynamicSqlInsertList" useGeneratedKeys="true" keyProperty="id"> insert into users (name, age, county, date) values <foreach collection="list" item="user" separator="," > (#{user.name}, #{user.age}, #{user.county}, #{user.date}) </foreach> </insert>
從結(jié)果可以看出,我們一下插入了兩條數(shù)據(jù),每條數(shù)據(jù)之間使用“,”進(jìn)行分割,separator="," 的作用就是如此。其中< foreach >標(biāo)簽內(nèi)部的屬性務(wù)必加上item.。
list集合參數(shù)
<!--動(dòng)態(tài)Sql: foreach標(biāo)簽, list參數(shù)查詢--> <select id="dynamicSqlSelectList" resultType="com.lks.domain.User"> SELECT * from users WHERE id in <foreach collection="list" item="id" open="(" close=")" separator="," > #{id} </foreach> </select>
可以看出我們的 SQL 語(yǔ)句新增了:( ? , ? ) ,前后的括號(hào)由 open="(" close=")" 進(jìn)行控制,用“?”占位符占位,并通過(guò)separator以:“,”隔開(kāi),內(nèi)部?jī)蓚€(gè)循環(huán)遍歷出的元素。array 集合與 list 的做法也是類似的:
<!--動(dòng)態(tài)Sql: foreach標(biāo)簽, array參數(shù)查詢--> <select id="dynamicSqlSelectArray" resultType="com.lks.domain.User"> select * from users WHERE id in <foreach collection="array" item="id" open="(" close=")" separator=","> #{id} </foreach> </select>
map參數(shù)
< map> 標(biāo)簽需要結(jié)合MyBatis的參數(shù)注解 @Param()來(lái)使用,需要告訴Mybatis配置文件中的collection="map"里的map是一個(gè)參數(shù):
<!--動(dòng)態(tài)Sql: foreach標(biāo)簽, map參數(shù)查詢--> <select id="dynamicSqlSelectMap" resultType="com.lks.bean.User"> select * from users WHERE <foreach collection="map" index="key" item="value" separator="="> ${key} = #{value} </foreach> </select>
需要主要${}和#{}的使用。
到此這篇關(guān)于Mybatis動(dòng)態(tài)SQL的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Mybatis動(dòng)態(tài)SQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MybatisPlus使用idworker解決雪花算法重復(fù)
本文主要介紹了MybatisPlus使用idworker解決雪花算法重復(fù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題
這篇文章主要介紹了SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Java保留兩位小數(shù)的幾種寫(xiě)法總結(jié)
相信大家在平時(shí)做項(xiàng)目時(shí),可能會(huì)有這樣的業(yè)務(wù)需求: 頁(yè)面或界面上展示的數(shù)據(jù)保留小數(shù)點(diǎn)后兩位。 那么這篇文章小編就和大家分享了利用Java保留兩位小數(shù)的幾種寫(xiě)法,文章給出了詳細(xì)的示例代碼,對(duì)大家的學(xué)習(xí)和理解很有幫助,有需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。2016-11-11Spring Boot如何使用JDBC獲取相關(guān)的數(shù)據(jù)詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot如何使用JDBC獲取相關(guān)數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Java實(shí)現(xiàn)List集合手動(dòng)分頁(yè)的方法
在工作中難免會(huì)遇到,將組裝的集合數(shù)據(jù)進(jìn)行分頁(yè)處理,本文主要介紹了Java實(shí)現(xiàn)List集合手動(dòng)分頁(yè)的方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03