第9章 MyBatis的動態(tài)SQL電子課件_第1頁
第9章 MyBatis的動態(tài)SQL電子課件_第2頁
第9章 MyBatis的動態(tài)SQL電子課件_第3頁
第9章 MyBatis的動態(tài)SQL電子課件_第4頁
第9章 MyBatis的動態(tài)SQL電子課件_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第9章MyBatis的動態(tài)SQL《JavaEE企業(yè)級應(yīng)用開發(fā)教程(Spring+SpringMVC+MyBatis)(第3版)》學(xué)習(xí)目標(biāo)/Target掌握

<foreach>

標(biāo)簽的使用,能夠使用

<foreach>

標(biāo)簽遍歷數(shù)組、List和Map掌握<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽的使用,能夠使用<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽動態(tài)地構(gòu)建SQL語句掌握<if>標(biāo)簽的使用,能夠使用<if>標(biāo)簽動態(tài)地構(gòu)建SQL語句掌握條件拼接和修剪標(biāo)簽的使用,能夠使用<where>標(biāo)簽和<trim>標(biāo)簽動態(tài)地拼接和修剪SQL語句的片段掌握更新操作標(biāo)簽的使用,能夠使用<set>標(biāo)簽根據(jù)條件動態(tài)地生成SET子句章節(jié)概述/Summary在程序中操作數(shù)據(jù)庫時,經(jīng)常需要根據(jù)業(yè)務(wù)需求對SQL語句進行拼接,如果進行手動拼接,不僅要求開發(fā)人員處理空格、標(biāo)點符號等瑣碎細節(jié),而且容易增加代碼的復(fù)雜性,并提高出錯的可能性。為解決這一問題,MyBatis提供了強大的動態(tài)SQL功能,動態(tài)SQL指運行時動態(tài)組裝SQL語句的技術(shù)。MyBatis的動態(tài)SQL功能允許開發(fā)人員利用簡潔的標(biāo)簽和語法,根據(jù)實際需求動態(tài)生成SQL語句,輕松實現(xiàn)復(fù)雜的SQL操作。根據(jù)功能來劃分,實現(xiàn)動態(tài)SQL的標(biāo)簽可以分為條件判斷標(biāo)簽、循環(huán)遍歷標(biāo)簽、條件拼接和修剪標(biāo)簽、更新操作標(biāo)簽。下面將對MyBatis的動態(tài)SQL進行講解。目錄/Contents9.19.2條件判斷標(biāo)簽循環(huán)遍歷標(biāo)簽9.3條件拼接和修剪標(biāo)簽9.4更新操作標(biāo)簽條件判斷標(biāo)簽9.19.1

條件判斷標(biāo)簽MyBatis實現(xiàn)動態(tài)SQL時,條件判斷可以進一步細分為根據(jù)單個條件的真假進行判斷和根據(jù)多個條件分支進行判斷,其中前者可以通過<if>標(biāo)簽實現(xiàn),后者則可以通過<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽實現(xiàn),下面分別對這兩類條件判斷標(biāo)簽進行講解。9.1.1

<if>標(biāo)簽先定一個小目標(biāo)!

先定一個小目標(biāo)!掌握<if>標(biāo)簽的使用,能夠使用<if>標(biāo)簽動態(tài)地構(gòu)建SQL語句9.1.1

<if>標(biāo)簽<if>標(biāo)簽可以根據(jù)指定的條件表達式的結(jié)果動態(tài)生成SQL語句,它提供了test屬性用于指定條件表達式,該表達式的值為true或false。如果條件表達式的值為true,則包含<if>標(biāo)簽內(nèi)部的SQL語句;如果條件表達式的值為false,則不包含。test屬性指定的條件表達式可以使用OGNL(ObjectGraphNavigationLanguage,對象導(dǎo)航圖語言)表達式、比較運算符、邏輯運算符等進行構(gòu)建。例如,test="name!=null"表示當(dāng)name不為null時條件成立,test="name!=nullandname!=''”表示當(dāng)name不為null并且name的值不為空字符串時條件成立。9.1.1

<if>標(biāo)簽1.數(shù)據(jù)庫數(shù)據(jù)準(zhǔn)備在名稱為mybatis的數(shù)據(jù)庫中,創(chuàng)建存儲圖書信息的數(shù)據(jù)表book,并插入幾條測試數(shù)據(jù),具體代碼如下文件9-1所示。文件9-1book.sql源代碼假設(shè)有一個需要根據(jù)圖書id和名稱查詢圖書信息的需求,圖書id和名稱都是可選的查詢條件,這個時候可以使用<if>標(biāo)簽動態(tài)地構(gòu)建SQL語句進行查詢。下面通過案例演示這個查詢的實現(xiàn)。9.1.1

<if>標(biāo)簽2.創(chuàng)建項目在IDEA中創(chuàng)建一個名稱為chapter09的Maven項目,并在項目的pom.xml文件中引入MyBatis、MySQL連接、單元測試的相關(guān)依賴,具體如文件9-2所示。文件9-2pom.xml源代碼9.1.1

<if>標(biāo)簽3.創(chuàng)建實體類在項目的src/main/java目錄下創(chuàng)建包com.itheima.entity,并在該包中創(chuàng)建與數(shù)據(jù)表book對應(yīng)的實體類Book,用于存儲圖書信息,具體如文件9-3所示。文件9-3Book.java源代碼9.1.1

<if>標(biāo)簽4.創(chuàng)建Mapper接口在項目的src/main/java目錄下創(chuàng)建包com.itheima.mapper,并在該包中創(chuàng)建操作Book對象和數(shù)據(jù)庫數(shù)據(jù)映射的Mapper接口BookMapper,并在該接口中定義方法queryByIdAndName(),該方法接收Book類型的參數(shù),具體如文件9-4所示。文件9-4BookMapper.java源代碼9.1.1

<if>標(biāo)簽5.創(chuàng)建核心配置文件在項目的src/main/resources目錄下創(chuàng)建一個名稱為mybatis-config.xml的文件作為MyBatis的核心配置文件,在mybatis-config.xml配置文件中配置數(shù)據(jù)庫連接信息和映射器相關(guān)信息,具體如9-5所示。文件9-5mybatis-config.xml源代碼9.1.1

<if>標(biāo)簽6.創(chuàng)建映射文件在src/main/resources目錄下創(chuàng)建多級文件夾com/itheima/mapper,在該文件夾下創(chuàng)建一個名稱為BookMapper.xml的文件,在該文件中定義查詢語句,用于根據(jù)傳入Book對象的id和名稱查詢對應(yīng)的圖書信息,如果圖書id和名稱不為null時,則根據(jù)對應(yīng)的id和名稱進行查詢,具體如文件9-6所示。文件9-6BookMapper.xml源代碼9.1.1

<if>標(biāo)簽7.定義測試方法在項目的src/test/java目錄下創(chuàng)建BookTest類,為了減少冗余代碼,在此將創(chuàng)建SqlSession對象的代碼抽取成獨立的方法createSqlSession(),并定義測試方法ifTest(),在測試方法中通過SqlSession對象獲取BookMapper對象,并通過BookMapper對象調(diào)用其queryByIdAndName()方法查詢圖書信息,具體如文件9-7所示。文件9-7BookTest.java源代碼9.1.1

<if>標(biāo)簽8.測試效果運行文件9-7中的ifTest()方法,運行效果如下圖所示。9.1.1

<if>標(biāo)簽8.測試效果將文件9-7中第35行代碼修改為b.setName("西游記");后運行文件9-7中的ifTest()方法,運行效果如下圖所示。9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽先定一個小目標(biāo)!

先定一個小目標(biāo)!掌握<if>標(biāo)簽的使用,能夠使用<if>標(biāo)簽動態(tài)地構(gòu)建SQL語句在MyBatis中,<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽適用于多條件選擇和復(fù)雜的條件邏輯下的SQL語句編寫,基于這三個標(biāo)簽程序會從多個備選項中選擇一個滿足條件的選項創(chuàng)建動態(tài)SQL語句。下面對這三個標(biāo)簽分別進行說明。9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽<choose>標(biāo)簽類似于Java中的switch語句,用于從多個備選項中選擇一個滿足條件的選項,它可以包含零個或多個<when>標(biāo)簽和零個或一個<otherwise>標(biāo)簽。<choose>標(biāo)簽會依次檢查每個<when>標(biāo)簽的條件表達式,如果條件表達式的值為true,則該<when>標(biāo)簽內(nèi)部的SQL片段會被包含到最終生成的SQL語句中;如果所有<when>子標(biāo)簽的條件表達式都不為true,并且存在<otherwise>標(biāo)簽,則<otherwise>標(biāo)簽內(nèi)部的SQL片段會被包含到最終生成的SQL語句中。(1)<choose>標(biāo)簽9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽<when>標(biāo)簽用于定義<choose>標(biāo)簽中的備選條件,它包含一個test屬性,用于指定條件表達式。(2)<when>標(biāo)簽(3)<otherwise>標(biāo)簽<otherwise>標(biāo)簽是可選的標(biāo)簽,用于指定當(dāng)所有<when>標(biāo)簽的條件都不滿足時,默認包含到最終生成的SQL語句中的SQL片段。9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽1.定義查詢方法在文件9-4中的BookMapper接口中定義查詢圖書并排序的方法findBooksWithSort(),該方法的參數(shù)為排序的字段名稱,具體如下所示。假設(shè)有一個需要查詢圖書信息時根據(jù)圖書名稱或價格對圖書信息進行升序排序的需求,如果沒有指定圖書名稱或價格排序時,則默認根據(jù)圖書id排序,這個時候可以使用<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽動態(tài)地構(gòu)建SQL語句進行查詢。下面通過案例演示這個查詢的實現(xiàn)。List<Book>findBooksWithSort(StringsortType);9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽2.編寫映射信息在文件9-6中定義根據(jù)傳入的參數(shù)排序的圖書查詢語句,依次判斷傳入的排序參數(shù)是否為name或者price,如果是,根據(jù)傳入的參數(shù)升序排序,否則根據(jù)id升序排序,具體代碼如下。圖書查詢語句源代碼9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽3.定義測試方法在文件9-7的BookTest類中定義測試方法chooseTest(),在該方法中獲取BookMapper對象,并使用BookMapper對象調(diào)用其findBooksWithSort()方法查詢圖書信息并進行排序,具體代碼如下所示。測試方法源代碼9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽4.測試效果運行文件9-7中的chooseTest()方法,運行效果如下圖所示。9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽4.測試效果將chooseTest()方法中傳入findBooksWithSort()的參數(shù)修改為price后,運行chooseTest()方法,運行效果如下圖所示。9.1.2<choose>標(biāo)簽、<when>標(biāo)簽和<otherwise>標(biāo)簽4.測試效果將chooseTest()方法中傳入findBooksWithSort()的參數(shù)修改為name和price之外的其他值,例如修改為空字符串,運行chooseTest()方法,運行效果如下圖所示。循環(huán)遍歷標(biāo)簽9.29.2

循環(huán)遍歷標(biāo)簽先定一個小目標(biāo)!

先定一個小目標(biāo)!掌握

<foreach>

標(biāo)簽的使用,能夠使用

<foreach>

標(biāo)簽遍歷數(shù)組、List和Map9.2

循環(huán)遍歷標(biāo)簽在實際開發(fā)中,開發(fā)者常常會遇到需要進行批量操作的任務(wù),這些任務(wù)往往具有一定的規(guī)律性和重復(fù)性,例如,批量更新用戶信息、批量插入訂單等。如果采用硬編碼的方式逐一編寫SQL語句,不僅工作量大,且代碼難以維護,容易出錯。為了解決這類問題,可以使用MyBatis基于循環(huán)遍歷的動態(tài)SQL實現(xiàn)。MyBatis的<foreach>標(biāo)簽?zāi)軌虮闅v數(shù)組和集合,并根據(jù)數(shù)組或集合中的元素動態(tài)生成SQL語句。通過這種方式,開發(fā)者可以更加靈活地處理批量操作,減少重復(fù)性工作,提高代碼的可維護性和可讀性。下面將對<foreach>標(biāo)簽進行講解。9.2

循環(huán)遍歷標(biāo)簽1.<foreach>標(biāo)簽的屬性屬性說明item用于指定遍歷過程中每個元素的別名,在循環(huán)體中可以通過該別名引用當(dāng)前迭代的元素,該屬性為必選index用于指定在遍歷過程中當(dāng)前元素的索引值。如果遍歷的是List集合和數(shù)組,索引值就是當(dāng)前元素在集合和數(shù)組中的下標(biāo);如果遍歷的是Map集合,索引值為集合中的鍵的名稱open用于指定循環(huán)開始處插入的字符串separator用于指定每次迭代之間插入的分隔符close與open相對應(yīng),用于定義在循環(huán)結(jié)束處插入的字符串,用于包圍循環(huán)內(nèi)容的終止符號9.2

循環(huán)遍歷標(biāo)簽屬性說明collection用于指定遍歷的可迭代對象,collection屬性的取值的常見情況如下。如果傳入的是單個參數(shù)且參數(shù)類型是一個array數(shù)組,那么collection的屬性值可以為array或者是傳入?yún)?shù)的名稱,傳入?yún)?shù)的名稱可以在Mapper接口對應(yīng)方法的簽名中使用@Param注解指定,格式為@Param("參數(shù)名稱")如果傳入的是單參數(shù)且參數(shù)類型是一個List,那么collection的屬性值可以為list或參數(shù)名稱如果傳入的參數(shù)是多個,需要把它們封裝成一個Map,那么collection的屬性值可以是傳入?yún)?shù)的名稱。如果Map存放的鍵值對中,值為可迭代對象,那collection的屬性值可以設(shè)置為鍵的名稱,迭代對應(yīng)的值9.2

循環(huán)遍歷標(biāo)簽2.<foreach>標(biāo)簽遍歷數(shù)組(1)定義查詢方法在文件9-4中的BookMapper接口中定義根據(jù)多個圖書id查詢對應(yīng)圖書信息的方法findBooksByIds(),具體如下所示。下面通過傳入多個圖書id批量查詢圖書信息的案例,演示<foreach>標(biāo)簽遍歷數(shù)組的使用。List<Book>findBooksByIds(Integer[]ids);9.2

循環(huán)遍歷標(biāo)簽(2)編寫映射信息在文件9-6中定義查詢語句,在查詢語句中遍歷傳入的數(shù)組,根據(jù)數(shù)組中的元素查找對應(yīng)的圖書信息,具體代碼如下。<selectid="findBooksByIds"resultType="com.itheima.entity.Book">

SELECT*FROMbookWHEREidIN

<foreachitem="id"collection="array"open="("separator=","close=")"> #{id}

</foreach></select>9.2

循環(huán)遍歷標(biāo)簽(3)定義測試方法在文件9-7的BookTest類中定義測試方法foreachByArrayTest(),在該方法中獲取BookMapper對象,并使用BookMapper對象調(diào)用其findBooksByIds()方法查詢圖書信息并進行排序,具體代碼如下所示。foreachByArrayTest()方法源代碼9.2

循環(huán)遍歷標(biāo)簽(4)測試效果運行文件9-7中的foreachByArrayTest()方法,運行效果如下圖所示。9.2

循環(huán)遍歷標(biāo)簽3.<foreach>標(biāo)簽遍歷List(1)定義插入方法在文件9-4中的BookMapper接口中定義批量插入圖書信息的方法findBooksByIds(),該方法的參數(shù)為排序的字段名稱,具體如下所示。下面通過批量插入多個圖書信息的案例,演示<foreach>標(biāo)簽遍歷List的使用。voidbatchInsertBooks(List<Book>books);9.2

循環(huán)遍歷標(biāo)簽(2)編寫映射信息在文件9-6中定義批量插入圖書信息的語句,遍歷傳入的List,將迭代到的元素作為插入到數(shù)據(jù)表中的記錄,具體代碼如下。<insertid="batchInsertBooks"parameterType="java.util.List"> INSERTINTObook(id,name,price)VALUES <foreachcollection="list"item="book"separator=","> (#{book.id},#{},#{book.price}) </foreach></insert>9.2

循環(huán)遍歷標(biāo)簽(3)定義測試方法在文件9-7的BookTest類中定義測試方法foreachByListTest(),在該方法中獲取BookMapper對象,并使用BookMapper對象調(diào)用其batchInsertBooks()方法批量插入圖書信息,具體代碼如下所示。foreachByListTest()方法源代碼9.2

循環(huán)遍歷標(biāo)簽(4)測試效果運行文件9-7中的foreachByListTest()方法,運行效果下圖所示。9.2

循環(huán)遍歷標(biāo)簽4.<foreach>標(biāo)簽遍歷Map(1)定義查詢方法在文件9-4中的BookMapper接口中定義根據(jù)多個查詢條件查詢圖書信息的方法queryByConditions(),該方法的參數(shù)為封裝到Map中的查詢條件,具體如下所示。下面通過根據(jù)多個查詢條件查詢圖書信息的案例,演示<foreach>標(biāo)簽遍歷Map的使用。List<Book>queryByConditions(@Param("conditions")Map<String,String>conditions);9.2

循環(huán)遍歷標(biāo)簽(2)編寫映射信息在文件9-6中定義根據(jù)多個查詢條件查詢圖書信息的查詢語句,遍歷傳入的Map參數(shù),將迭代到的鍵和值作為SQL語句的查詢條件,具體代碼如下。<selectid="queryByConditions"parameterType="map"resultType="com.itheima.entity.Book"> SELECT*FROMbook WHERE1=1 <foreachitem="item"index="key"collection="conditions"open="AND("separator="OR"close=")"> ${key}=#{item} </foreach></select>9.2

循環(huán)遍歷標(biāo)簽(3)定義測試方法在文件9-7的BookTest類中定義測試方法foreachByMapTest(),在該方法中獲取BookMapper對象,并使用BookMapper對象調(diào)用其queryByConditions()方法根據(jù)多個查詢條件查詢圖書信息,具體代碼如下所示。foreachByMapTest()方法源代碼9.2

循環(huán)遍歷標(biāo)簽(4)測試效果運行文件9-7中的foreachByMapTest()方法,運行效果如下圖所示。條件拼接和修剪標(biāo)簽9.39.3條件拼接和修剪標(biāo)簽先定一個小目標(biāo)!

先定一個小目標(biāo)!掌握條件拼接和修剪標(biāo)簽的使用,能夠使用<where>標(biāo)簽和<trim>標(biāo)簽動態(tài)地拼接和修剪SQL語句的片段9.3條件拼接和修剪標(biāo)簽在構(gòu)建動態(tài)SQL時,根據(jù)業(yè)務(wù)邏輯的不同,我們通常需要動態(tài)地拼接和修剪SQL語句的片段,以確保生成的SQL既符合語法規(guī)則又能準(zhǔn)確表達查詢意圖。MyBatis為此提供了強大的條件拼接和修剪標(biāo)簽,其中最為常用的便是<where>標(biāo)簽和<trim>標(biāo)簽。下面對這兩個標(biāo)簽分別進行講解。9.3條件拼接和修剪標(biāo)簽在前兩節(jié)的案例映射文件的查詢語句中,因為不確定條件判斷是否能成立,對此在條件之前加入了“WHERE1=1”,以避免條件判斷成立后WHERE后面第一個詞是AND或者OR之類的關(guān)鍵字出現(xiàn)語法錯誤。但這種做法可能會讓SQL語句看起來不太自然,同時會引入額外的邏輯或者不必要的查詢條件,而不符合業(yè)務(wù)需求。對此,可以使用<where>標(biāo)簽動態(tài)的條件拼接。<where>標(biāo)簽是MyBatis中用于動態(tài)構(gòu)建SQL查詢條件的標(biāo)簽之一,<where>

標(biāo)簽會確保只有當(dāng)至少有一個條件成立時,才會在SQL語句中添加WHERE關(guān)鍵字,并且可以自動處理條件語句中的AND和OR關(guān)鍵字,從而構(gòu)建正確的SQL查詢語句。使用<where>標(biāo)簽可以使SQL查詢語句的編寫更加簡潔和靈活,尤其是在存在多個條件需要動態(tài)拼接時。1.<where>標(biāo)簽9.3條件拼接和修剪標(biāo)簽(1)修改映射文件修改文件9-6中id為queryByIdAndName的查詢語句,使用<where>標(biāo)簽替換“WHERE1=1”,修改后代碼如下。下面基于9.1.1節(jié)<if>標(biāo)簽的案例,使用<where>標(biāo)簽替換“WHERE1=1”演示<where>標(biāo)簽的使用。修改后的查詢語句源代碼9.3條件拼接和修剪標(biāo)簽(2)測試效果運行文件9-7中的ifTest()方法,運行效果如下圖所示。9.3條件拼接和修剪標(biāo)簽<trim>標(biāo)簽是MyBatis中用于修剪SQL語句字符的標(biāo)簽,它通常用于動態(tài)構(gòu)建SQL查詢語句時,根據(jù)條件動態(tài)地添加或者刪除指定的字符,以構(gòu)建符合預(yù)期邏輯的SQL語句。MyBatis的<trim>標(biāo)簽具有一系列用于修剪SQL語句的屬性,通過這些屬性開發(fā)者可以精細地控制SQL語句的修剪,具體如下。2.<trim>標(biāo)簽屬性說明prefix指定給SQL語句增加的前綴字符串prefixOverrides指定SQL語句中要去掉的前綴字符串suffix指定給SQL語句增加的后綴字符串suffixOverrides指定SQL語句中要去掉的后綴字符串9.3條件拼接和修剪標(biāo)簽(1)修改映射信息修改文件9-6中id為queryByIdAndName的查詢語句,使用<trim>標(biāo)簽替換“WHERE1=1”,修改后代碼如下。下面同樣基于9.1.1節(jié)<if>標(biāo)簽的案例,使用<trim>標(biāo)簽替換“WHERE1=1”演示<trim>標(biāo)簽的使用

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論