亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mybatis中的@Param及動(dòng)態(tài)SQL詳解

 更新時(shí)間:2023年10月08日 08:54:40   作者:童話ing  
這篇文章主要介紹了Mybatis中的@Param及動(dòng)態(tài)SQL詳解,@Param是MyBatis所提供的作為Dao層的注解,作用是用于傳遞參數(shù),從而可以與SQL中的的字段名相對(duì)應(yīng),需要的朋友可以參考下

一、@Param注解

@Param 是MyBatis所提供的作為Dao層的注解,作用是用于傳遞參數(shù),從而可以與SQL中的的字段名相對(duì)應(yīng)。

首先需要明確一下 @Param 和 @RequestParam 雖然看起來(lái)有那么一點(diǎn)相似,但其實(shí)是沒(méi)有任何關(guān)系的,就像 魚(yú)香茄子 和 魚(yú) 一樣。

注解來(lái)源
@Paramorg.apache.ibatis.annotations.Param
@RequestParamorg.springframework.web.bind.annotation.RequestParam

@RequestParam作用于Controller層,作用是為獲取前端參數(shù),解決的是前后端參數(shù)不一致的問(wèn)題。@Param作用于Dao層,是為了傳遞多個(gè)參數(shù),解決的是可讀性和直觀性;所以它們沒(méi)有關(guān)系!

我們簡(jiǎn)單看一下使用:

List<PreEndBlogListVO> selectBlogListByTypeId(@Param("typeId") Integer id);

上述 @Param 作用其實(shí)就是將 id 重命名為 typeId 。因此,我們可以在xml中這樣使用:

  <select id="selectBlogListByTypeId" resultMap="preEndBlogListMap">
       select id,title,description from blog where type_id=#{typeId,jdbcType=INTEGER}
  </select>

并且當(dāng)參數(shù)來(lái)自于多個(gè)不同POJO時(shí)候,使用@Param后,Mybatis會(huì)自動(dòng)檢索參數(shù)類型,也就是不用再在xml中配置 parameterType 屬性了。

public List<Role> findRoleByMix(@Param("roleP") RoleParam role, @Param("permissionP") PermissionParam permission);

xml配置:

<select id="findRoleByMix" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleP.roleName}
    AND note=#{rolep.note}
    AND level=#{permissionP.level}
<select>

二、Mybatis動(dòng)態(tài)SQL

以前在使用JDBC操作數(shù)據(jù)時(shí),如果查詢條件特別多,將條件串聯(lián)成SQL字符串是一件痛苦的事情。通常的解決方法是寫(xiě)很多的if-else條件語(yǔ)句對(duì)字符串進(jìn)行拼接,并確保不能忘了空格或在字段的最后省略逗號(hào)。MyBatis使用動(dòng)態(tài)SQL來(lái)改善這種情形,動(dòng)態(tài)SQL是基于OGNL的表達(dá)式,可方便我們?cè)赟QL語(yǔ)句中實(shí)現(xiàn)某些邏輯,簡(jiǎn)單說(shuō)主要是為了解決參數(shù)不固定情況。用于實(shí)現(xiàn)動(dòng)態(tài)SQL的元素如下。

  • if:利用if實(shí)現(xiàn)簡(jiǎn)單的條件選擇
  • choose(when,otherwise):相當(dāng)于Java中的switch語(yǔ)句,通常與when和otherwise搭配使用
  • set:解決動(dòng)態(tài)更新語(yǔ)句
  • trim:可以靈活的去除多余的關(guān)鍵字
  • foreach:迭代一個(gè)集合,通常用于in條件

set 標(biāo)簽

使用set標(biāo)簽可以將動(dòng)態(tài)的配置 SET 關(guān)鍵字,并剔除追加到條件末尾的任何不相關(guān)的逗號(hào)。使用 if+set 標(biāo)簽修改后,在進(jìn)行表單更新的操作中,哪個(gè)字段中有值才去更新,如果某項(xiàng)為 null 則不進(jìn)行更新,而是保持?jǐn)?shù)據(jù)庫(kù)原值。

<update id="updateSet" parameterType="com.dl.POJO.User">
     update user
     <set>
         <if test="name != null and name != ''">
             name = #{name},
         </if>
         <if test="county != null and county != ''">
             county = #{county},
         </if>
     </set>
     where id = #{id}
 </update>

大多數(shù)標(biāo)簽我們都是結(jié)合在一起使用的,常見(jiàn)主要是為了解決參數(shù)不固定情況。

2.1 if 和 where 標(biāo)簽

<sql id="params">
  id, name,country,sex,birth,tel
</sql>
<select id="selectByConditions"  resultType="com.dl.POJO.User">
  select <include refid="params"/> from user
  <where>
      <if test="id != null and id != 0">
          AND id = #{id}
      </if>
      <if test="name != null and name != ''">
          AND name = #{name}
      </if>
      <if test="county != null and county != ''">
          AND county = #{county}
      </if>
  </where>
</select>

<include refid="params"/>其實(shí)就是你需要查詢的sql字段,用一個(gè)sql標(biāo)簽封裝起來(lái),以后直接引用即可。

一般開(kāi)發(fā)列表業(yè)務(wù)的查詢條件時(shí),參數(shù)通常不固定,如果有多個(gè)查詢條件,通常會(huì)使用<where> <if>標(biāo)簽來(lái)進(jìn)行控制。

where標(biāo)簽會(huì)自動(dòng)標(biāo)識(shí)其標(biāo)簽內(nèi)是否有返回值,若有,就插入一個(gè)where。 <where>標(biāo)簽可以

自動(dòng)的將第一個(gè)滿足的條件前面的邏輯運(yùn)算符 (or ,and) 去掉,什么意思呢,我們簡(jiǎn)單看一下:

假設(shè)此時(shí)我們傳入的參數(shù)為:id=0 name="童話" country="中國(guó)"

觀察傳入的參數(shù),id傳入0,此條件不會(huì)執(zhí)行。name傳入一個(gè)合法值,此時(shí)name條件成立,但是前面多了一個(gè)and關(guān)鍵字,此時(shí)<where>標(biāo)簽會(huì)自動(dòng)去掉這個(gè)and關(guān)鍵字。

當(dāng)然,有的人可能會(huì)說(shuō),后面直接給個(gè)where 1=1不就可以不用<where>標(biāo)簽了么。如下所示:

<select id="findActiveBlogLike" resultType="Blog">
    select * from blog
    where 1=1
   <if test="state != null">
     and state = #{state}
   </if> 
</select>

當(dāng)然,這樣肯定是能實(shí)現(xiàn)你所想的功能的做法,但這個(gè)東西也會(huì)帶來(lái)一個(gè)巨坑,但是這種做法有一個(gè)最大的弊端,如果表有索引的話,會(huì)導(dǎo)致數(shù)據(jù)表上的索引失效。這樣查詢得效率顯然就會(huì)很低下,就像 ${} 和 #{} 多數(shù)情況下可以通用,但是${}就是不能防止SQL注入問(wèn)題。因此我們還是采用 <where> 標(biāo)簽比較舒適。

如果 where 元素不能滿足你的要求,你也可以通過(guò)自定義 trim 元素來(lái)定制 where 元素的功能。

2.2 trim和if標(biāo)簽

mybatis的trim標(biāo)簽一般用于去除sql語(yǔ)句中多余的and關(guān)鍵字,逗號(hào),或者給sql語(yǔ)句前拼接 where 、 set 以及 values( 等前綴,或者添加“)“等后綴,可用于選擇性插入、更新、刪除或者條件查詢等操作。

主要有4個(gè)屬性:

屬性描述
prefix給sql語(yǔ)句拼接的前綴
suffix給sql語(yǔ)句拼接的后綴
prefixOverrides去除sql語(yǔ)句前面的關(guān)鍵字或者字符,該關(guān)鍵字或者字符由prefixOverrides屬性指定,假設(shè)該屬性指定為"AND",當(dāng)sql語(yǔ)句的開(kāi)頭為"AND",trim標(biāo)簽將會(huì)去除該"AND"
suffixOverrides去除sql語(yǔ)句后面的關(guān)鍵字或者字符,該關(guān)鍵字或者字符由suffixOverrides屬性指定

舉個(gè)栗子,和 where 元素等價(jià)的自定義 trim 元素為:

<select id="getUserList" resultType="com.dl.POJO.User">
  select <include refid="params"/> from user
  <trim prefix="where" prefixOverrides="and | or" suffix="order by id">
      <if test="id != null and id != 0">
          AND id = #{id}
      </if>
      <if test="name != null and name != ''">
          AND name = #{name}
      </if>
      <if test="county != null and county != ''">
          AND county = #{county}
      </if>
  </trim>
</select>

上面我們多添加了一個(gè) suffix="order by id" 來(lái)實(shí)現(xiàn)按照某種規(guī)則排序,下面再看一個(gè)稍微復(fù)雜一點(diǎn)的栗子。

  <insert id="insertSelective" parameterType="com.dl.blog.pojo.Blog">
    insert into blog
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="title != null">
        title,
      </if>
      <if test="views != null">
        views,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="title != null">
        #{title,jdbcType=VARCHAR},
      </if>
      <if test="views != null">
        #{views,jdbcType=INTEGER},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>

其中最重要的就是 suffixOverrides="," ,表示去除sql語(yǔ)句結(jié)尾多余的逗號(hào)。 假設(shè)上述條件只匹配上前三個(gè),可以看到我們的sql將變成

insert into blog(id,title,views,) values(1,"標(biāo)題",22,)

此時(shí)插入將會(huì)失敗。使用trim標(biāo)簽就可以輕松解決此問(wèn)題。

2.3 foreach 標(biāo)簽

foreach標(biāo)簽主要有以下參數(shù):

屬性描述
item循環(huán)體中的具體對(duì)象。支持屬性的點(diǎn)路徑訪問(wèn),如item.age,item.info.details,在list和數(shù)組中是其中的對(duì)象,在map中是value。
index在list和數(shù)組中,index是元素的序號(hào),在map中,index是元素的key,該參數(shù)可選。
open表示該語(yǔ)句以什么開(kāi)始
close表示該語(yǔ)句以什么結(jié)束
separator表示元素之間的分隔符,例如在in()的時(shí)候,separator=","會(huì)自動(dòng)在元素中間用“,“隔開(kāi),避免手動(dòng)輸入逗號(hào)導(dǎo)致sql錯(cuò)誤,如in(1,2,)這樣。該參數(shù)可選。

栗子1:進(jìn)行l(wèi)ist批量插入

<insert id="dynamicSqlInsertList" useGeneratedKeys="true" keyProperty="id" parameterType="java.util.List">
    insert into users (name, age, county, date)
    values
    <foreach collection="list" item="user" separator="," >
        (#{user.name}, #{user.age}, #{user.county}, #{user.date})
    </foreach>
</insert>

特別注意:Mysql默認(rèn)接受sql的大小是 1048576(1M), 即第三種方式若數(shù)據(jù)量超過(guò)1M會(huì)報(bào)如下異常:(可通過(guò)調(diào)整MySQL安裝目錄下的 my.ini 文件中 [mysqld] 段的 max_allowed_packet = 1M )

useGeneratedKeys="true" keyProperty="id" 是用于插入之后返回自增主鍵的id的

在這里插入圖片描述

從結(jié)果可以看出,我們一下插入了兩條數(shù)據(jù),每條數(shù)據(jù)之間使用 “,” 逗號(hào)進(jìn)行分割, separator="," 的作用就是如此。其中 < foreach > 標(biāo)簽內(nèi)部的屬性務(wù)必加上 item。

與上面批量插入對(duì)應(yīng)的mapper代碼如下:

int insert(List<User> userList);

當(dāng)然,其實(shí)說(shuō)到批量插入,最粗暴方法就是for循環(huán)直接插入,但是數(shù)據(jù)量越多,耗費(fèi)的時(shí)間將是巨大的。 

記錄條數(shù)普通for循環(huán)Mybatis batchforeach標(biāo)簽
500條77427388622
1000條1529015078746
5000條780111773501172
10000條3974722011801205

栗子2:list集合參數(shù)

<select id="dynamicSqlSelectList" resultType="com.dl.POJO.User">
     SELECT * from user WHERE id in
     <foreach collection="list" item="id" open="(" close=")" separator="," >
         #{id}
     </foreach>
 </select>

在這里插入圖片描述

可以看出我們的 SQL 語(yǔ)句新增了:( ? , ? ) ,前后的括號(hào)由 open="(" close=")" 進(jìn)行控制,用 “?” 占位符占位,并通過(guò)separator以:“,”隔開(kāi),內(nèi)部?jī)蓚€(gè)循環(huán)遍歷出的元素。

栗子3:map參數(shù) < map> 標(biāo)簽需要結(jié)合MyBatis的參數(shù)注解 @Param() 來(lái)使用,需要告訴Mybatis配置文件中的 collection="map" 里的map是一個(gè)參數(shù):

<select id="dynamicSqlSelectMap" resultType="com.lks.bean.User">
     select * from users WHERE
     <foreach collection="map" index="key" item="value"  separator="=">
         ${key} = #{value}
     </foreach>
 </select>

2.4 choose、when、otherwise 標(biāo)簽

這三個(gè)標(biāo)簽需要組合在一起使用,類似于 Java 中的 switch、case、default。只有一個(gè)條件生效,也就是只執(zhí)行滿足的條件 when,沒(méi)有滿足的條件就執(zhí)行 otherwise,表示默認(rèn)條件。

 <select id="dynamicSql2" resultType="com.lks.domain.User">
     select * from users
     <where>
         <choose>
             <when test="name != null and name != ''">
                 AND name = #{name}
             </when>
             <when test="county != null and county != ''">
                 AND county = #{county}
             </when>
             <otherwise>
                 AND id = #{id}
             </otherwise>
         </choose>
     </where>
 </select>

即使同時(shí)添加name和county的值,最終的sql也只會(huì)添加第一個(gè)屬性值。

三、總結(jié)

使用批量插入執(zhí)行的SQL語(yǔ)句應(yīng)該等價(jià)于:

insert into users(name, age, county, date) values (?,?,?,? ),(?,?,?,? ),(?,?,?,? ),(?,?,?,?)

在使用foreach的時(shí)候最關(guān)鍵的也是最容易出錯(cuò)的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:

1.如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)List的時(shí)候,collection屬性值為list

2.如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)array數(shù)組的時(shí)候,collection的屬性值為array

3.如果傳入的參數(shù)是多個(gè)的時(shí)候,我們就需要把它們封裝成一個(gè)Map了,當(dāng)然單參數(shù)也可以封裝成map

到此這篇關(guān)于Mybatis中的@Param及動(dòng)態(tài)SQL詳解的文章就介紹到這了,更多相關(guān)Mybatis動(dòng)態(tài)sql及@Param內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • elasticsearch bucket 之rare terms聚合使用詳解

    elasticsearch bucket 之rare terms聚合使用詳解

    這篇文章主要為大家介紹了elasticsearch bucket 之rare terms聚合使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 使用SpringBoot實(shí)現(xiàn)自動(dòng)發(fā)送注冊(cè)驗(yàn)證碼郵件功能

    使用SpringBoot實(shí)現(xiàn)自動(dòng)發(fā)送注冊(cè)驗(yàn)證碼郵件功能

    一直以來(lái),我都對(duì)程序如何自動(dòng)發(fā)送郵件感到好奇,想象一下,當(dāng)你在某個(gè)網(wǎng)站注冊(cè)時(shí),輸入郵箱后不久就收到一封帶有驗(yàn)證碼的郵件,這種體驗(yàn)既方便又高效,所以本文給大家介紹了如何用?Spring?Boot?實(shí)現(xiàn)自動(dòng)發(fā)送注冊(cè)驗(yàn)證碼郵件,需要的朋友可以參考下
    2025-04-04
  • mybatisPlus實(shí)現(xiàn)倒序拼接字符串

    mybatisPlus實(shí)現(xiàn)倒序拼接字符串

    這篇文章主要介紹了mybatisPlus實(shí)現(xiàn)倒序拼接字符串方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • idea中創(chuàng)建maven的Javaweb工程并進(jìn)行配置(圖文教程)

    idea中創(chuàng)建maven的Javaweb工程并進(jìn)行配置(圖文教程)

    這篇文章主要介紹了idea中創(chuàng)建maven的Javaweb工程并進(jìn)行配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),文中給大家提到了tomcat的運(yùn)行方法,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Java Apache Shiro安全框架快速開(kāi)發(fā)詳解流程

    Java Apache Shiro安全框架快速開(kāi)發(fā)詳解流程

    Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證、授權(quán)、密碼和會(huì)話管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任何應(yīng)用程序,從最小的移動(dòng)應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序
    2021-10-10
  • 在eclipse中修改tomcat的部署路徑操作

    在eclipse中修改tomcat的部署路徑操作

    這篇文章主要介紹了在eclipse中修改tomcat的部署路徑操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • SpringSecurity6.4中一次性令牌登錄(One-Time Token Login)實(shí)現(xiàn)

    SpringSecurity6.4中一次性令牌登錄(One-Time Token Login)實(shí)現(xiàn)

    Spring Security為一次性令牌認(rèn)證提供了支持,本文就來(lái)介紹一下SpringSecurity6.4中一次性令牌登錄(One-Time Token Login)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • 詳解Java中的Reflection反射和暴力反射

    詳解Java中的Reflection反射和暴力反射

    本文主要介紹了詳解Java中的Reflection反射和暴力反射,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • JDK1.7的ConcurrentHashMap源碼解析

    JDK1.7的ConcurrentHashMap源碼解析

    這篇文章主要介紹了JDK1.7的ConcurrentHashMap源碼解析,HashMap是非線程安全的,而HashTable是線程安全的,但是HashTable實(shí)現(xiàn)同步的方法比較暴力,即在所有的方法體上添加synchronized關(guān)鍵字,需要的朋友可以參考下
    2023-12-12
  • maven的settings.xml、pom.xml配置文件使用詳解

    maven的settings.xml、pom.xml配置文件使用詳解

    本文詳解了Maven中的配置文件settings.xml和pom.xml,闡述了它們的作用、配置項(xiàng)以及優(yōu)先級(jí)順序,settings.xml存在于Maven安裝目錄和用戶目錄下,分別作用于全局和當(dāng)前用戶,pom.xml位于項(xiàng)目根路徑下
    2024-09-09

最新評(píng)論