<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MyBatis 多條件查詢、動態(tài)SQL、多表操作、注解開發(fā),應(yīng)有盡有,一...

          共 6903字,需瀏覽 14分鐘

           ·

          2022-09-16 10:15

          點擊關(guān)注公眾號,Java干貨 及時送達(dá) 9aadd43e241c064c9aecbdfcf84d460a.webp

          來源:iyu77.blog.csdn.net/article/details/125761737

          MyBatis封裝了JDBC通過Mapper代理的方式,以前繁瑣的操作通過“屬性與字段映射”就簡單化解,MyBatis的動態(tài)SQL完美展現(xiàn)了DBMS的獨特魅力。

          一、多條件查詢

          基于Mybatis的多條件查詢,是在Mapper代理的映射文件中寫上原有的SQL,然后接口中寫一個帶參的方法即可,就像這樣:

          093ff27f3494e01c92b451ce1448e994.webp

          相比于原生的JDBC那一套,通過MyBatis確實解決了不少硬編碼的問題

          但是用戶的查詢永遠(yuǎn)是動態(tài)的操作,他可能在多個條件中選擇其中少量條件進(jìn)行查詢,我們的SQL是死的,而用戶需求對應(yīng)的SQL卻是活的,這樣就會造成不匹配而形成語法錯誤

          比如,根據(jù)這張表,若是要根據(jù)部分字段查出整體,我們可以寫對應(yīng)需求的SQL,但是我要是查詢的條件變少了或者變多了呢?若用戶只想通過一個條件來查詢,那么在其他占位符的位置不輸入于是成了null,過不了語法自然查不了,還得重新寫SQL,多麻煩

          92991224e87b46c2a486ac5c99ded0b3.webp

          這個時候MyBatis的特色就體現(xiàn)出來了——動態(tài)SQL。

          二、動態(tài)SQL

          SQL語句會隨著用戶的輸入或者外部條件的變化而變化,則稱之為動態(tài)SQL。另外,最新 MyBatis?系列面試題整理好了,大家可以在Java面試庫小程序在線刷題。

          1. if-where

          因為采用了Mapper代理開發(fā),我們可以通過寫xml的形式來編寫我們的SQL,動態(tài)SQL的特性也就在這一舉動中所蘊育,在原有的Mapper文件里我們進(jìn)行如下改造,讓平平無奇的SQL煥然一新:

                <select?id="selByCondition"?resultMap="rm">
          ????select?*
          ????from?mybatis
          ????<where>
          ????<if?test="status?!=null">
          ???????and?STATUS=#{STATUS}
          ????</if>
          ????<if?test="companyName?!=null?and?companyName?!=''">
          ????and?company_name?like?#{companyName}
          ????</if>
          ????<if?test="bracdName?!=null?and?bracdName?!=''">
          ????and?bracd_name?like?#{bracdName}
          ????</if>
          ????</where>
          </select>

          <where>標(biāo)簽可以自動幫我們?nèi)サ鬭nd”,這樣,不管查詢的條件怎么變,我跟著這個邏輯流程走就不會出現(xiàn)SQL語法毛病而導(dǎo)致查詢不出來的毛病啦,因為null的情況已經(jīng)被if所過濾掉了,真是太哇塞了!

          2. choose-when-ortherwise

          對于從多個條件中選擇一個的單條件查詢的場景,利用分支嵌套就可以實現(xiàn)動態(tài)選擇單條件:

          在MyBatis的Mapper代理中,<choose>相當(dāng)于switch,<when>相當(dāng)于case

                <select?id="selByCondition2"?resultMap="rm">
          ????select?*
          ????from?mybatis?where
          ????<choose>
          ????????<when?test="status?!=null">
          ????????????STATUS=#{STATUS}
          ????????</when>
          ????????<when?test="companyName?!=null?and?companyName?!=''">
          ????????????company_name?like?#{companyName}
          ????????</when>
          ????????<when?test="bracdName?!=null?and?bracdName?!=''">
          ????????????bracd_name?like?#{bracdName}
          ????????</when>
          ????????<otherwise>1=1</otherwise>
          ????</choose>
          </select>

          與多條件查詢不同的是,SQL語句中只會有一個分支生效

          當(dāng)用戶一個條件都不選時,可以在<otherwise>中寫上1=1讓語法成立,反之,若選擇了條件則會返回正常結(jié)果。

          推薦一個開源免費的 Spring Boot 最全教程:https://github.com/javastacks/spring-boot-best-practice

          3. foreach

          對于批量刪除的場景,傳統(tǒng)的方法是通過in關(guān)鍵字結(jié)合占位符來確定,就像這樣

                where?id?in?(?,?,?)

          但對于動態(tài)的場景,批量的數(shù)量永遠(yuǎn)是不確定的,這就導(dǎo)致還需要去改SQL里的占位符數(shù)量啊,又是一件麻煩事

          PS:MyBatis會將數(shù)組參數(shù)封裝成一個Map集合,默認(rèn)情況(K-V)array=數(shù)組。

          下面使用了@Param注解改變了map集合中默認(rèn)的key

          1f96a87cc527e8a0e898a861b8b2cff2.webp

          于是MyBatis中的<foreach>解決了這一麻煩。

          本質(zhì)是通過遍歷的形式,批量刪除的數(shù)據(jù)是由id數(shù)組或者集合來決定,collection屬性決定了要遍歷哪個數(shù)組/集合,item屬性則來存放選出的元素,并把它放在占位符里,separator屬性表示分隔符

                <delete?id="deleteById">
          ????delete?frpm?mybatis?where?id?in
          ????<foreach?collection="ids"?item="id"?separator=","?open="("?close=")">
          ????????#{id}
          ????</foreach>;
          </delete>

          有人會問為啥這里只有一個#{id},我的屬性字段不止這一個呀?此id非彼id他是一個數(shù)組/集合。

          0a532bd1bac0ac8f217db8f9e37c2123.webp

          三、多表操作

          多表之間的關(guān)系有一對一,一對多,多對一,多對多,每一種都有建表的原則,以用戶-訂單模型為例

          利用傳統(tǒng)的方法進(jìn)行多表查詢無非是通過id來連接表然后封裝返回結(jié)果,MyBatis中也是如此,我們在Mapper文件中寫好表字段之間的映射關(guān)系,定義好類型即可,只不過這一過程有點復(fù)雜,但一次配好之后即可極大減少硬編碼問題,提高效率。

          1. 一對一

          一個用戶有一張訂單

          7f55928b8171a37e0b71cc1f9cb6f7e5.webp

          首先還是那套路,建好實體類,寫好接口方法,配置Mapper文件,而多表操作的麻煩點就在于配置文件,這里通過例子細(xì)說一下

          1.先把表寫好
                CREATE?TABLE?orders?(
          id?INT?PRIMARY?KEY?,
          ordertime?VARCHAR(20)?NOT?NULL?DEFAULT?'',
          total?DOUBLE,
          uid?INT);
          INSERT?INTO?orders?VALUES(1,2020,2000,1);
          INSERT?INTO?orders?VALUES(2,2021,3000,2);
          INSERT?INTO?orders?VALUES(3,2022,4000,3);
          CREATE?TABLE?USER?(
          id?INT?PRIMARY?KEY?,
          username?VARCHAR(50)?NOT?NULL?DEFAULT?'',
          passwords?VARCHAR(50)?NOT?NULL?DEFAULT?'');
          INSERT?INTO?USER?VALUES(1,'lyy',333);
          INSERT?INTO?USER?VALUES(2,'myy',444);
          INSERT?INTO?USER?VALUES(3,'xyy',555);
          2.寫Mapper配置文件

          在寫實體類時,要把一個實體寫到另一個實體的屬性里面,這樣才體現(xiàn)關(guān)聯(lián)性,就比如“訂單是所用戶擁有的”,正因為這種關(guān)系我們才會在訂單實體類里面寫上private User user;這一屬性,這樣根據(jù)id連接的兩個實體才能完美對接!

          就像這樣:

          11079689a7ecd8e0ef06282edd59f53b.webp

          通過<association>把兩張表對應(yīng)的實體類連接起來,只不過是主鍵ID要用單獨的標(biāo)簽

          • property: 當(dāng)前實體(order)中的屬性名稱(private User user)
          • javaType: 當(dāng)前實體(order)中的屬性的類型(User)

          這兩個user有著本質(zhì)上的卻別,就好像前者是在一個人的名字,后者正是被叫的那個人,MyBatis好像就利用了這一特性,通過標(biāo)簽的形式連接了兩個實體

                <select?id="findAll"?resultMap="orderMap">
          ???SELECT?*,o.id?oid?FROM?orders?o,USER?u?WHERE?o.uid=u.id
          </select>

          SQL環(huán)節(jié)和原來沒什么區(qū)別,同樣也是通過resultMap把字段和屬性映射封裝。點擊關(guān)注公眾號,Java干貨及時送達(dá)9aadd43e241c064c9aecbdfcf84d460a.webp

          2.一對多

          一個用戶有多張訂單

          cb57972e4c59e35662d3b99e56ef0905.webp

          首先,在原有的User實體中得加上一個表示“用戶有哪些訂單的屬性”private List<Order> orderList;,目的是為了把訂單的信息封裝到用戶的這個屬性里,在Mapper文件中體現(xiàn):

                <collection?property="orderList"?ofType="order">
          ????<!--封裝order的數(shù)據(jù)-->
          ????<id?column="oid"?property="id"></id>
          ????<result?column="ordertime"?property="ordertime"></result>
          ????<result?column="total"?property="total"></result>
          </collection>
          • property:集合名稱,User實體中的orderlist屬性
          • ofType:當(dāng)前集合中的數(shù)據(jù)類型,就是order實體

          然后就是寫一對多的SQL:

                <select?id="findAll"?resultMap="userMap">
          ???SELECT?*,o.id?oid?FROM?USER?u,orders?o?WHERE?u.id=o.uid
          </select>

          總結(jié)來看,一對多相比于一對一就是在那個“一”中增添了封裝“多”的屬性而已,然后稍微調(diào)整一下SQL。另外,最新 MyBatis?系列面試題整理好了,大家可以在Java面試庫小程序在線刷題。

          3.多對多

          多用戶多角色

          d517f07ddb4500dff29d5c5b3ec0b70e.webp

          多對多的建表原則是引入一張中間表,用于維護(hù)外鍵,就是一張表通過中間表找到另一張表

          和一對多的模型類似,先在User實體類中增添一個“用戶具備哪些角色”的屬性private List roleList;其次配置Mapper文件:

                
                  <collection?property="roleList"?ofType="role">
          ???<id?column="roleId"?property="id"></id>
          ???<result?column="roleName"?property="roleName"></result>
          ???<result?column="roleDesc"?property="roleDesc"></result>
          </collection>

          多表的連接是靠中間表,這點在Mapper文件中通過映射實現(xiàn),具體是把兩張外表的id(userId和roleId)在id標(biāo)簽中配置成同一個屬性,就像這樣:

                
                  <id?column="userId"?property="id"></id>
          <id?column="roleId"?property="id"></id>

          SQL環(huán)節(jié)就得用多對多的套路了

                
                  <select?id="findUserAndRoleAll"?resultMap="userRoleMap">
          ????SELECT?*?FROM?USER?u,user-role?ur,role?r?WHERE?u.id=ur.userId?AND?ur.roleId=r.id
          </select>

          回想進(jìn)行多表操作時MyBatis為我們帶來了什么?他確實減少了很多硬編碼,我每一次新的SQL只需要在標(biāo)簽里改幾個屬性就可以,只要理清字段與屬性的映射關(guān)系,在MyBatis中進(jìn)行多表操作就是一個“對號入座”。

          四、注解開發(fā)

          針對于簡單的CRUD注解開發(fā)可以極大地提升效率,顧名思義就是把SQL寫在注解里

          查詢(@Select):

          27ead64636f591fd53cf2849e1646200.webp

          添加(@Insert):

          014277930da73c3ffe324c19388449ae.webp

          修改(@Update):

          7d04ad118e13e128a9669ecde28c1d51.webp

          刪除(@Delete) :

          dd61afeca4d711d2bf87dc0f55136096.webp87ba4d83ba9af39ae0bc9d2f706b7892.webp
          Spring Boot 學(xué)習(xí)筆記,這個太全了! 23 種設(shè)計模式實戰(zhàn)(很全) Nacos 2.1.1 正式發(fā)布,真心強(qiáng)! 阿里一面:Spring Bean 如何保證并發(fā)安全? MyBatis 批量插入別再亂用 foreach 了! 10c322d0dd5bfd8dec82355f4bb15403.webpSpring Cloud 微服務(wù)最新教程!
          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费黄色电影在线网站 | 中国免费毛片 | 午夜性爱免费视频 | 国产精品综合久久久久久 | 草操视频 |