0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MyBatis動態(tài)sql是什么?MyBatis動態(tài)SQL最全教程

jf_ro2CN3Fa ? 來源:CSDN ? 2023-08-10 10:18 ? 次閱讀

一、MyBatis動態(tài) sql 是什么

動態(tài) SQL 是 MyBatis 的強大特性之一。在 JDBC 或其它類似的框架中,開發(fā)人員通常需要手動拼接 SQL 語句。根據(jù)不同的條件拼接 SQL 語句是一件極其痛苦的工作。例如,拼接時要確保添加了必要的空格,還要注意去掉列表最后一個列名的逗號。而動態(tài) SQL 恰好解決了這一問題,可以根據(jù)場景動態(tài)的構(gòu)建查詢。

動態(tài)SQL(code that is executed dynamically),它一般是根據(jù)用戶輸入或外部條件動態(tài)組合的SQL語句塊。 動態(tài)SQL能靈活的發(fā)揮SQL強大的功能、方便的解決一些其它方法難以解決的問題。 相信使用過動態(tài)SQL的人都能體會到它帶來的便利,然而動態(tài)SQL有時候在執(zhí)行性能 (效率)上面不如靜態(tài)SQL,而且使用不恰當(dāng),往往會在安全方面存在隱患 (SQL 注入式攻擊)。

1.Mybatis 動態(tài) sql 是做什么的?

Mybatis 動態(tài) sql 可以讓我們在 Xml 映射文件內(nèi),以標(biāo)簽的形式編寫動態(tài) sql,完成邏輯判斷和動態(tài)拼接 sql 的功能。

2.Mybatis 的 9 種 動 態(tài) sql 標(biāo) 簽有哪些?

元素 作用 備注
if 判斷語句 單條件分支判斷
choose(when、otherwise) 相當(dāng)于 Java 中的 switch case 語句 多條件分支判斷
trim,where 輔助元素 用于處理一些SQL拼裝問題
foreach 循環(huán)語句 在in語句等列舉條件常用
bind 輔助元素 拼接參數(shù)

3.動態(tài) sql 的執(zhí)行原理?

原理為:使用 OGNL 從 sql 參數(shù)對象中計算表達式的值,根據(jù)表達式的值動態(tài)拼接 sql,以此來完成動態(tài) sql 的功能。

二、MyBatis標(biāo)簽

1.if標(biāo)簽:條件判斷

MyBatis if 類似于 Java 中的 if 語句,是 MyBatis 中最常用的判斷語句。使用 if 標(biāo)簽可以節(jié)省許多拼接 SQL 的工作,把精力集中在 XML 的維護上。

1)不使用動態(tài)sql


 
select*fromuserwhereusername=#{username}andsex=#{sex}

if 語句使用方法簡單,常常與 test 屬性聯(lián)合使用。語法如下:

SQL語句

2)使用動態(tài)sql

上面的查詢語句,我們可以發(fā)現(xiàn),如果 #{username} 為空,那么查詢結(jié)果也是空,如何解決這個問題呢?使用 if 來判斷,可多個 if 語句同時使用。

以下語句表示為可以按照網(wǎng)站名稱(name)或者網(wǎng)址(url)進行模糊查詢。如果您不輸入名稱或網(wǎng)址,則返回所有的網(wǎng)站記錄。但是,如果你傳遞了任意一個參數(shù),它就會返回與給定參數(shù)相匹配的記錄。


selectid,name,urlfromwebsite
where1=1

ANDnamelike#{name}


ANDurllike#{url}


2.where+if標(biāo)簽

where、if同時使用可以進行查詢、模糊查詢

注意,失敗后, 關(guān)鍵字只會去掉庫表字段賦值前面的and,不會去掉語句后面的and關(guān)鍵字,即注意, 只會去掉 語句中的最開始的and關(guān)鍵字。所以下面的形式是不可取的





sacclikeconcat('%'#{sacc}'%')


ANDsnamelikeconcat('%'#{sname}'%')


ANDsex=#{sex}


ANDphone=#{phone}



這個“where”標(biāo)簽會知道如果它包含的標(biāo)簽中有返回值的話,它就插入一個‘where’。此外,如果標(biāo)簽返回的內(nèi)容是以AND 或OR 開頭的,則它會剔除掉。

3.set標(biāo)簽

set可以用來修改


updatestudent

sname=#{sname},
spwd=#{spwd},
sex=#{sex},
phone=#{phone}
sid=#{sid}

wheresid=#{sid}

4.choose(when,otherwise) 語句

有時候,我們不想用到所有的查詢條件,只想選擇其中的一個,查詢條件有一個滿足即可,使用 choose 標(biāo)簽可以解決此類問題,類似于 Java 的 switch 語句


select*fromuser



id=#{id}


andusername=#{username}


andsex=#{sex}




也就是說,這里我們有三個條件,id、username、sex,只能選擇一個作為查詢條件

如果 id 不為空,那么查詢語句為:select * from user where id=?

如果 id 為空,那么看username 是否為空,如果不為空,那么語句為 select * from user where username=?;

如果 username 為空,那么查詢語句為 select * from user where sex=?

5.trim

trim標(biāo)記是一個格式化的標(biāo)記,可以完成set或者是where標(biāo)記的功能

①、用 trim 改寫上面第二點的 if+where 語句


select*fromuser
 


andusername=#{username}


andsex=#{sex}



prefix:前綴

prefixoverride:去掉第一個and或者是or

②、用 trim 改寫上面第三點的 if+set 語句

 

updateuseru
 


u.username=#{username},


u.sex=#{sex},



whereid=#{id}

suffix:后綴

suffixoverride:去掉最后一個逗號(也可以是其他的標(biāo)記,就像是上面前綴中的and一樣)

③、trim+if同時使用可以添加


insertintostudent

sname,
spwd,
sex,
phone,



#{sname},
#{spwd},
#{sex},
#{phone}



6.MyBatis foreach標(biāo)簽

foreach是用來對集合的遍歷,這個和Java中的功能很類似。通常處理SQL中的in語句。

foreach 元素的功能非常強大,它允許你指定一個集合,聲明可以在元素體內(nèi)使用的集合項(item)和索引(index)變量。它也允許你指定開頭與結(jié)尾的字符串以及集合項迭代之間的分隔符。這個元素也不會錯誤地添加多余的分隔符

你可以將任何可迭代對象(如 List、Set 等)、Map 對象或者數(shù)組對象作為集合參數(shù)傳遞給 foreach。當(dāng)使用可迭代對象或者數(shù)組時,index 是當(dāng)前迭代的序號,item 的值是本次迭代獲取到的元素。當(dāng)使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值。

//批量查詢

WHEREsidin

#{ids}


//批量刪除

deletefromstudentwheresidin

#{ids}


整合案例

xml





select*fromstudent








WHERE1=1

ANDsidlike#{sid}







sacclikeconcat('%'#{sacc}'%')


ANDsnamelikeconcat('%'#{sname}'%')


ANDsex=#{sex}


ANDphone=#{phone}





updatestudent

sname=#{sname},
spwd=#{spwd},
sex=#{sex},
phone=#{phone}
sid=#{sid}

wheresid=#{sid}



insertintostudent

sname,
spwd,
sex,
phone,



#{sname},
#{spwd},
#{sex},
#{phone}




WHEREsidin

#{ids}




deletefromstudentwheresidin

#{ids}






測試類:

packagecom.yzx.test;

importcom.yzx.entity.Student;
importcom.yzx.mapper.StuMapper;
importorg.apache.ibatis.io.Resources;
importorg.apache.ibatis.session.SqlSession;
importorg.apache.ibatis.session.SqlSessionFactory;
importorg.apache.ibatis.session.SqlSessionFactoryBuilder;
importorg.junit.After;
importorg.junit.Before;
importorg.junit.Test;

importjava.io.IOException;
importjava.io.InputStream;
importjava.util.List;

publicclassStuTest{
SqlSessionsqlSession=null;
InputStreamis=null;

@Before
publicvoidbefore()throwsIOException{
//1.讀取核心配置文件
is=Resources.getResourceAsStream("sqlMapperConfig.xml");
//2.拿到工廠構(gòu)建類
SqlSessionFactoryBuildersqlSessionFactoryBuilder=newSqlSessionFactoryBuilder();
//3.拿到具體工廠
SqlSessionFactorybuild=sqlSessionFactoryBuilder.build(is);
//4.拿到session
sqlSession=build.openSession();
}

@After
publicvoidafter(){
//7,提交事務(wù)
sqlSession.commit();
//8.關(guān)閉資源
sqlSession.close();
if(is!=null){
try{
is.close();
}catch(IOExceptione){
e.printStackTrace();
}
};
}

//查詢所有
@Test
publicvoidfind(){
//5.獲取具體的mapper接口
StuMappermapper=sqlSession.getMapper(StuMapper.class);
//6.調(diào)用執(zhí)行
Listlist=mapper.find();
list.forEach(a->System.out.println(a));
}
//查詢單個
@Test
publicvoidfindbyid(){

StuMappermapper=sqlSession.getMapper(StuMapper.class);
Listlist=mapper.findbyid(2);
list.forEach(a->System.out.println(a));
}
//模糊查詢
@Test
publicvoidfindQuery(){

StuMappermapper=sqlSession.getMapper(StuMapper.class);

Studentstu=newStudent();
stu.setSname("小");
stu.setSex("男");
Listlist=mapper.findQuery(stu);
list.forEach(a->System.out.println(a));
}
//修改
@Test
publicvoidupd(){

StuMappermapper=sqlSession.getMapper(StuMapper.class);

Studentstu=newStudent();
stu.setSid(3);
stu.setSname("小若");
stu.setSex("人妖");
inti=mapper.upd(stu);
System.out.println("修改了"+i+"條數(shù)據(jù)"+""+stu.toString());

}
//添加
@Test
publicvoidadd(){

StuMappermapper=sqlSession.getMapper(StuMapper.class);

Studentstu=newStudent();
stu.setSname("小賀");
stu.setSex("男");
stu.setPhone("99999999");
inti=mapper.add(stu);
System.out.println("添加了"+i+"條數(shù)據(jù)"+""+stu.toString());

}

//批量操作
@Test
publicvoidfindAll(){

StuMappermapper=sqlSession.getMapper(StuMapper.class);
Integer[]i={1,2,3,4};
Listlist=mapper.findAll(i);
list.forEach(a->System.out.println(a));
}
//批量操作

//批量刪除
@Test
publicvoiddel(){
StuMappermapper=sqlSession.getMapper(StuMapper.class);
Integer[]i={1,2,3,4};
inti1=mapper.del(i);
System.out.println("刪除了"+i1+"條數(shù)據(jù)");
}
}

7.sql

在實際開發(fā)中會遇到許多相同的SQL,比如根據(jù)某個條件篩選,這個篩選很多地方都能用到,我們可以將其抽取出來成為一個公用的部分,這樣修改也方便,一旦出現(xiàn)了錯誤,只需要改這一處便能處處生效了,此時就用到了這個標(biāo)簽了。

當(dāng)多種類型的查詢語句的查詢字段或者查詢條件相同時,可以將其定義為常量,方便調(diào)用。為求

9.如何引用其他XML中的SQL片段

比如你在com.xxx.dao.xxMapper這個Mapper的XML中定義了一個SQL片段如下:

ID,MAJOR,BIRTHDAY,AGE,NAME,HOBBY

此時我在com.xxx.dao.PatinetMapper中的XML文件中需要引用,如下:

三、MyBatis關(guān)聯(lián)查詢

1.MyBatis一對多關(guān)聯(lián)查詢

 












 

select*fromstudent1sleftjointeachertons.sid=t.sid

2.MyBatis多對一關(guān)聯(lián)查詢

 













 

select*fromteachertrightjoinstudent1sont.sid=s.sid

3.MyBatis多對多關(guān)聯(lián)查詢

 

select*fromstudent1sleftjoinrelevancerons.sid=r.sidleftjointeachertonr.tid=t.tid





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    764

    瀏覽量

    44134
  • JAVA語言
    +關(guān)注

    關(guān)注

    0

    文章

    138

    瀏覽量

    20095
  • XML技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    15

    瀏覽量

    6011
  • UTF-8
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    7855
  • mybatis
    +關(guān)注

    關(guān)注

    0

    文章

    60

    瀏覽量

    6714

原文標(biāo)題:MyBatis 動態(tài) SQL 最全教程,這樣寫 SQL 太爽了!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Mybatis的特點和核心配置文件

    Mybatis—01基礎(chǔ)&動態(tài)SQL
    發(fā)表于 08-07 14:20

    為什么要動態(tài)sql語句?

    為什么要動態(tài)sql語句?因為動態(tài)sql語句能夠提供一些比較友好的機制1、可以使得一些在編譯過程中無法獲得完整的sql語句,在程序執(zhí)行階段
    發(fā)表于 12-20 06:00

    jdbc與mybatis的區(qū)別

    MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。JDBC是一種用于執(zhí)行SQL
    發(fā)表于 02-02 17:43 ?1.1w次閱讀
    jdbc與<b class='flag-5'>mybatis</b>的區(qū)別

    mybatis是什么_MyBatis的優(yōu)缺點詳解_mybatis框架入門詳解

    Mybatis框架是別人開發(fā)的一種半成品軟件,可以用來通過定制輔助快速開發(fā)是工具。MyBatis應(yīng)用程序根據(jù)XML配置文件創(chuàng)建SqlSessionFactory,SqlSessionFactory在
    發(fā)表于 02-24 09:16 ?2w次閱讀

    mybatis動態(tài)sql詳解

    本文詳細介紹了mybatis執(zhí)行動態(tài)sql語句的方法。
    發(fā)表于 02-24 11:37 ?3839次閱讀

    mybatis中#和$的區(qū)別

    ${ } 變量的替換階段是在動態(tài) SQL 解析階段,而 #{ }變量的替換是在 DBMS 中。這是 #{} 和 ${} 我們能看到的主要的區(qū)別,除此之外,還有以下區(qū)別:#方式能夠很大程度防止sql
    發(fā)表于 02-24 13:35 ?2273次閱讀

    在使用MyBatisSQL語句優(yōu)化總結(jié)

    MyBatis 作為一款優(yōu)秀的持久層框架,它支持自定義SQL、存儲過程以及高級映射。它免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。還可以通過簡單的 XML 或注解來配置和映射原始
    的頭像 發(fā)表于 02-04 15:20 ?2798次閱讀

    Fluent Mybatis、原生MybatisMybatis Plus對比

    使用fluent mybatis可以不用寫具體的xml文件,通過java api可以構(gòu)造出比較復(fù)雜的業(yè)務(wù)sql語句,做到代碼邏輯和sql邏輯的合一。不再需要在Dao中組裝查詢或更新操作,在xml或
    的頭像 發(fā)表于 09-15 15:41 ?1436次閱讀

    MybatisSQL注入審計的基本方法

    SQL注入漏洞作為WEB安全的最常見的漏洞之一,在java中隨著預(yù)編譯與各種ORM框架的使用,注入問題也越來越少。新手代碼審計者往往對Java Web應(yīng)用的多個框架組合而心生畏懼,不知如何下手,希望通過Mybatis框架使用不當(dāng)導(dǎo)致的S
    的頭像 發(fā)表于 10-17 11:16 ?1313次閱讀

    一文掌握MyBatis動態(tài)SQL使用與原理

    摘要:使用動態(tài) SQL 并非一件易事,但借助可用于任何 SQL 映射語句中的強大的動態(tài) SQL 語言,M
    的頭像 發(fā)表于 01-06 11:27 ?989次閱讀

    動態(tài)Sql介紹

    動態(tài)Sql介紹 動態(tài) SQLMyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應(yīng)該能理解根據(jù)不同條件拼接
    的頭像 發(fā)表于 05-31 09:34 ?1387次閱讀
    <b class='flag-5'>動態(tài)</b><b class='flag-5'>Sql</b>介紹

    什么是SQL注入?Java項目防止SQL注入方式

    Java項目防止SQL注入方式 這里總結(jié)4種: PreparedStatement防止SQL注入 mybatis中#{}防止SQL注入 對請求參數(shù)的敏感詞匯進行過濾 ngin
    發(fā)表于 10-16 14:26 ?611次閱讀

    mybatis接口動態(tài)代理原理

    MyBatis是一款輕量級的Java持久化框架,它通過XML或注解配置的方式,將數(shù)據(jù)庫操作與SQL語句解耦,提供了一種簡單、靈活的數(shù)據(jù)訪問方式。在MyBatis中,使用動態(tài)代理技術(shù)來實
    的頭像 發(fā)表于 12-03 11:52 ?948次閱讀

    mybatis和mybatisplus的區(qū)別

    個輕量級的持久層框架,它提供了一個靈活的SQL映射機制,使得開發(fā)者可以編寫原生SQL語句來操作數(shù)據(jù)庫。MyBatis的設(shè)計目標(biāo)是將原生SQL和對象關(guān)系映射(ORM)相結(jié)合,以便開發(fā)者可
    的頭像 發(fā)表于 12-03 11:53 ?2563次閱讀

    mybatis中$和井號區(qū)別

    MyBatis是一個開源的Java持久層框架,它提供了許多強大的功能用于簡化數(shù)據(jù)庫操作。在MyBatis中,我們可以使用兩種方式來動態(tài)生成SQL語句:$和#。 和#都可以用來替換
    的頭像 發(fā)表于 12-03 14:53 ?979次閱讀