一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - Java教程 - MyBatis中動(dòng)態(tài)sql的實(shí)現(xiàn)方法示例

MyBatis中動(dòng)態(tài)sql的實(shí)現(xiàn)方法示例

2021-06-11 13:18技術(shù)小能手 Java教程

這篇文章主要給大家介紹了關(guān)于MyBatis中動(dòng)態(tài)sql的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 動(dòng)態(tài)sql

動(dòng)態(tài)sql是mybatis中的一個(gè)核心,什么是動(dòng)態(tài)sql?

動(dòng)態(tài)sql即對(duì)sql語句進(jìn)行靈活操作,通過表達(dá)式進(jìn)行判斷,對(duì)sql進(jìn)行靈活拼接、組裝。

mybatis的強(qiáng)大特性之一便是它的動(dòng)態(tài) sql。如果你有使用 jdbc 或其他類似框架的經(jīng)驗(yàn),你就能體會(huì)到根據(jù)不同條件拼接 sql 語句有多么痛苦。拼接的時(shí)候要確保不能忘了必要的空格,還要注意省掉列名列表最后的逗號(hào)。有些時(shí)候,sql語句where條件中,需要一些安全判斷,例如按某一條件查詢時(shí)如果傳入的參數(shù)是空,此時(shí)查詢出的結(jié)果很可能是空的,也許我們需要參數(shù)為空時(shí),是查出全部的信息。使用oracle的序列、mysql的函數(shù)生成id。這時(shí)我們可以使用動(dòng)態(tài)sql。利用動(dòng)態(tài) sql 這一特性可以徹底擺脫這種痛苦。通常使用動(dòng)態(tài) sql 不可能是獨(dú)立的一部分,mybatis 當(dāng)然使用一種強(qiáng)大的動(dòng)態(tài) sql 語言來改進(jìn)這種情形,這種語言可以被用在任意的 sql 映射語句中。動(dòng)態(tài) sql 元素和使用 jstl 或其他類似基于 xml 的文本處理器相似。mybatis 采用功能強(qiáng)大的基于 ognl 的表達(dá)式來消除其他元素。

mybatis中用于實(shí)現(xiàn)動(dòng)態(tài)sql的元素主要有:

1、if和where

2、choose(when,otherwise)

3、trim

4、set

5、foreach

就拿上一篇博文中對(duì)用戶的綜合查詢一例來說:

?
1
select * from user where user.sex = #{user.sex} and user.username like '%${user.username}%'

假如這個(gè)user是null咋整?或者user.sex或者user.username為null呢?所以更嚴(yán)謹(jǐn)?shù)淖龇☉?yīng)該是在執(zhí)行這個(gè)語句之前要先進(jìn)行判斷才對(duì),確保都不為空,那么我再去查詢。這就涉及到了mybatis中的動(dòng)態(tài)sql了。

在mybatis中,動(dòng)態(tài)sql可以使用標(biāo)簽來表示,這很類似于jstl表達(dá)式,我們可以將上面的sql語句改成動(dòng)態(tài)sql,如下:

?
1
2
3
4
5
6
7
8
9
10
11
<select id="finduserlist" parametertype="mybatis.po.userqueryvo" resulttype="mybatis.po.user">
 select * from user <!-- where可以自動(dòng)去掉條件中的第一個(gè)and -->
 <where>
 <if test="user!=null">
 <if test="user.sex!=null and user.sex!=''">
 and user.sex = #{user.sex} </if>
 <if test="user.username!=null and user.username!=''">
 and user.username like '%${user.username}%' </if>
 </if>
 </where>
</select>

上面的代碼很好理解,主要就是加了一些判斷,條件不為空,才進(jìn)行查詢條件的拼接,讓mybatis動(dòng)態(tài)的去執(zhí)行。那么在測(cè)試代碼中,我們可以故意的將user.sex不賦初值,就可以看到查詢的結(jié)果是不一樣的。

2. sql片段

那么現(xiàn)在還有個(gè)問題,如果好幾個(gè)statement都需要這樣做,而且動(dòng)態(tài)sql部分都一樣,這就會(huì)導(dǎo)致一些代碼的重復(fù),所以如果遇到這種情況,我們就應(yīng)該抽取,動(dòng)態(tài)sql也可以抽取,我們可以將動(dòng)態(tài)的這部分sql抽取成sql片段,然后在具體的statement中引用進(jìn)來即可。如下:

?
1
2
3
4
5
6
7
8
<sql id="query_user_where">
 <if test="user!=null">
 <if test="user.sex!=null and user.sex!=''">
 and user.sex = #{user.sex} </if>
 <if test="user.username!=null and user.username!=''">
 and user.username like '%${user.username}%' </if>
 </if>
</sql>

id是給該sql片段起個(gè)名字而已,內(nèi)部就是上面的where動(dòng)態(tài)部分,然后我們將上面原來的動(dòng)態(tài)部分改成對(duì)這個(gè)sql片段的引用,如下:

?
1
2
3
4
5
6
7
<select id="finduserlist" parametertype="mybatis.po.userqueryvo" resulttype="mybatis.po.user">
 select * from user <where>
 <!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要在前面加上namespace -->
 <include refid="query_user_where"></include>
 <!-- 還可以引用其他sql片段 -->
 </where>
</select>

3. foreach

還有個(gè)問題:如果我們要向sql傳遞數(shù)組或list該咋整呢?mybatis使用的是foreach解析。為了模擬這個(gè)場(chǎng)景,我們將上面的查詢改成多個(gè)id查詢,有兩種查詢方式:

?
1
select * from user where id=1 or id=12 or id=17select * from user where id in(1,12,17)

首先有一點(diǎn)很明確,既然要使用多個(gè)id進(jìn)行查詢,那么多個(gè)id肯定要作為參數(shù)傳進(jìn)來,所以存儲(chǔ)多個(gè)id的list需要放到userqueryvo中作為一個(gè)屬性,這點(diǎn)很好理解,所以我們先在userqueryvo中增加這個(gè)屬性:

?
1
2
//傳入多個(gè)id
private list<integer> ids;

然后我們修改usermapper.xml中的sql片段(還是寫在sql片段中),如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<sql id="query_user_where">
 <if test="user!=null">
 <if test="user.sex!=null and user.sex!=''">
 and user.sex = #{user.sex} </if>
 <if test="user.username!=null and user.username!=''">
 and user.username like '%${user.username}%' </if>
 </if>
 <if test="ids!=null">
 <!-- 使用右邊的sql拼接:and (id=1 or id=12 or id=17) -->
 <foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
 id=#{user_id}
  </foreach>
 </if>
</sql>

下面簡單介紹一下這個(gè)foreach中相關(guān)屬性的作用:

collection:指定輸入對(duì)象中的集合屬性,這里就是這個(gè)ids。 item:表示每個(gè)遍歷生成的對(duì)象,自己起個(gè)名兒,在foreach體中使用。 open:開始遍歷時(shí)拼接的sql串。 close:結(jié)束遍歷時(shí)拼接的sql串。 separator:遍歷的兩個(gè)對(duì)象中需要拼接的sql串。

我們測(cè)試一下,然后看下控制臺(tái)打印出來的sql就很容易理解了。測(cè)試程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@testpublic void testfinduserlist() throws exception {
 
 sqlsession sqlsession = sqlsessionfactory.opensession();
 //創(chuàng)建usermapper對(duì)象,mybatis自動(dòng)生成mapper代理對(duì)象
 usermapper usermapper = sqlsession.getmapper(usermapper.class);
 
 //創(chuàng)建包裝對(duì)象,設(shè)置查詢條件
 userqueryvo userqueryvo = new userqueryvo();
 user user = new user();
 //由于這里使用動(dòng)態(tài)sql,如果不設(shè)置某個(gè)值,條件不會(huì)拼接在sql中
 user.setsex("男");
 user.setusername("倪升武");
 
 //傳入多個(gè)id
 list<integer> ids = new arraylist<integer>();
 ids.add(1);
 ids.add(12);
 ids.add(17);
 userqueryvo.setids(ids);
 
 userqueryvo.setuser(user);
 //調(diào)用usermapper的方法
 list<user> list = usermapper.finduserlist(userqueryvo);
 system.out.println(list);}

看下控制臺(tái)打印出的sql:

?
1
select * from user where user.sex = ? and user.username like '%倪升武%' and ( id=? or id=? or id=? )

注意一個(gè)細(xì)節(jié):在mybatis中,如果輸入的是integer或者int類型的0,上面那個(gè)if判斷標(biāo)簽返回的是false,也就是說,即使非空非'',也不會(huì)拼接標(biāo)簽體中的sql。

所以mybatis自動(dòng)的將多個(gè)id拼接到了sql中。那么另外一個(gè)sql的實(shí)現(xiàn)就不再贅述了,跟上面的一樣,唯一不同的就是sql片段部分,如下:

?
1
2
3
<!-- 使用右邊的sql拼接:and id in(1,12,17) -->
<foreach collection="ids" item="user_id" open="and id in(" close=")" separator=",">
 #{user_id}</foreach>

總結(jié):

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:https://yq.aliyun.com/articles/667279

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎影视紧急入口地址大全 | dasd-698黑人在线播放 | 天美影视文化传媒mv免费 | 免费黄色片网站 | 欧美一级乱妇老太婆特黄 | 天天做天天爰夜夜爽 | mmkk在线看片| 日韩xx00 | 精品精品国产自在久久高清 | ai换脸造梦jennie | 日韩毛片在线视频 | 热久久最新地址 | 亚洲国产精品久久人人爱 | 精品久久久久久综合网 | 男人的天堂视频在线 | 精品一卡2卡3卡4卡5卡亚洲 | 日本三级免费观看 | 亚洲欧美精品一区二区 | 欧美va在线| 欧美一区二区三区四区五区六区 | 欧美日韩国产一区二区三区欧 | 午夜神器老司机高清无码 | 欧美男男xxx激情做受 | 91精品国产品国语在线不卡 | 九草视频在线 | 日本在线亚州精品视频在线 | 亚洲免费视频在线 | 亚洲女同在线观看 | 国产亚洲福利精品一区 | 精品综合久久久久久97超人 | 99国产高清久久久久久网站 | 成人 在线欧美亚洲 | 久久偷拍国2017的 | 搞逼综合网 | 猫咪社区在线播放 | 黑人巨大和日本娇小中出 | 果冻传媒在线播放观看228集 | 色呦呦入口 | 2022国产麻豆剧果冻传媒入口 | 亚洲免费视频一区二区三区 | 无限在线看免费视频大全 |