最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis中動態(tài)sql的實現(xiàn)方法示例

 更新時間:2018年11月09日 15:30:17   作者:技術(shù)小能手  
這篇文章主要給大家介紹了關(guān)于MyBatis中動態(tài)sql的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 動態(tài)sql

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

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

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

MyBatis中用于實現(xiàn)動態(tài)SQL的元素主要有:

1、if和where

2、choose(when,otherwise)

3、trim

4、set

5、foreach

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

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

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

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

<select id="findUserList" parameterType="mybatis.po.UserQueryVo" resultType="mybatis.po.User">
 select * from user <!-- where可以自動去掉條件中的第一個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>

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

2. sql片段

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

<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片段起個名字而已,內(nèi)部就是上面的where動態(tài)部分,然后我們將上面原來的動態(tài)部分改成對這個sql片段的引用,如下:

<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

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

SELECT * FROM USER WHERE id=1 OR id=12 OR id=17SELECT * FROM USER WHERE id IN(1,12,17)

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

//傳入多個id
private List<Integer> ids;

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

<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>

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

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

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

@Testpublic void testFindUserList() throws Exception {
 
 SqlSession sqlSession = sqlSessionFactory.openSession();
 //創(chuàng)建UserMapper對象,mybatis自動生成mapper代理對象
 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 
 //創(chuàng)建包裝對象,設(shè)置查詢條件
 UserQueryVo userQueryVo = new UserQueryVo();
 User user = new User();
 //由于這里使用動態(tài)sql,如果不設(shè)置某個值,條件不會拼接在sql中
 user.setSex("男");
 user.setUsername("倪升武");
 
 //傳入多個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);}

看下控制臺打印出的sql:

select * from user WHERE user.sex = ? and user.username like '%倪升武%' AND ( id=? OR id=? OR id=? ) 

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

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

<!-- 使用右邊的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)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Spring Boot與Spark、Cassandra系統(tǒng)集成開發(fā)示例

    Spring Boot與Spark、Cassandra系統(tǒng)集成開發(fā)示例

    本文演示以Spark作為分析引擎,Cassandra作為數(shù)據(jù)存儲,而使用Spring Boot來開發(fā)驅(qū)動程序的示例。對spring boot 與spark cassandra集成開發(fā)示例代碼感興趣的朋友跟著腳本之家小編一起學(xué)習(xí)吧
    2018-02-02
  • Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)組件使用案例

    Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)

    這篇文章主要介紹了Java Swing中的下拉式菜單(menu)、彈出式菜單(JPopupMenu)、選項卡窗體(JTabbedPane)組件使用案例,需要的朋友可以參考下
    2014-10-10
  • springboot+redis實現(xiàn)簡單的熱搜功能

    springboot+redis實現(xiàn)簡單的熱搜功能

    這篇文章主要介紹了springboot+redis實現(xiàn)一個簡單的熱搜功能,通過代碼介紹了過濾不雅文字的過濾器,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • 基于Column注解的columnDefinition用法

    基于Column注解的columnDefinition用法

    這篇文章主要介紹了Column注解的columnDefinition用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring MVC中使用Controller如何進行重定向

    Spring MVC中使用Controller如何進行重定向

    這篇文章主要介紹了Spring MVC中使用Controller如何進行重定向操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    這篇文章主要介紹了C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法,相比普通方法能夠在Windows下簡化很多操作步驟,需要的朋友可以參考下
    2016-04-04
  • Spring中的@Qualifier注解和@Resource注解區(qū)別解析

    Spring中的@Qualifier注解和@Resource注解區(qū)別解析

    這篇文章主要介紹了Spring中的@Qualifier注解和@Resource注解區(qū)別解析,@Qualifier注解的用處是當(dāng)一個接口有多個實現(xiàn)的時候,為了指名具體調(diào)用哪個類的實現(xiàn),@Resource注解可以通過 byName命名和byType類型的方式注入,需要的朋友可以參考下
    2023-11-11
  • java中Spring Security的實例詳解

    java中Spring Security的實例詳解

    這篇文章主要介紹了java中Spring Security的實例詳解的相關(guān)資料,spring security是一個多方面的安全認證框架,提供了基于JavaEE規(guī)范的完整的安全認證解決方案,需要的朋友可以參考下
    2017-09-09
  • Java 線程的生命周期詳細介紹及實例代碼

    Java 線程的生命周期詳細介紹及實例代碼

    這篇文章主要介紹了Java 線程的生命周期的相關(guān)資料,并附簡單實例代碼,幫助大家理解,需要的朋友可以參考下
    2016-10-10
  • 你知道Spring如何解決所有循環(huán)依賴的嗎

    你知道Spring如何解決所有循環(huán)依賴的嗎

    這篇文章主要來和大家聊聊Spring?能解決所有循環(huán)依賴嗎,文中的示例代碼講解詳細,對我們學(xué)習(xí)Spring有一定的幫助,需要的小伙伴可以參考一下
    2023-07-07

最新評論

东平县| 江陵县| 新野县| 屏东市| 石门县| 花垣县| 章丘市| 涡阳县| 普格县| 三台县| 诏安县| 合山市| 苏州市| 福州市| 绵竹市| 湘潭县| 拜泉县| 潮州市| 沂南县| 多伦县| 友谊县| 阿拉善左旗| 汉川市| 华蓥市| 资阳市| 弥渡县| 姚安县| 弋阳县| 天等县| 吉木萨尔县| 永平县| 双鸭山市| 北安市| 东台市| 赤水市| 邹城市| 黄石市| 垦利县| 麻城市| 西林县| 新民市|