久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

Mybatis如何實(shí)現(xiàn)InsertOrUpdate功能

這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)InsertOrUpdate功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

實(shí)現(xiàn)InsertOrUpdate功能

需求

最近在項(xiàng)目開發(fā)中遇到這樣一個(gè)需求:每天需要對(duì)相同的數(shù)據(jù)(也有可能是不同的)進(jìn)行兩次入庫(kù)操作,數(shù)據(jù)不存在便insert,存在則update。于是就用到了Mybatis的InsertOrUpdate功能。

實(shí)現(xiàn)

每次操作數(shù)據(jù)庫(kù)之前,先根據(jù)id查詢有沒有記錄,有則進(jìn)行update操作,沒有則進(jìn)行insert操作。

model類代碼如下。其中count為非業(yè)務(wù)字段(也不是表sheet中的字段),只是方便Mybatis進(jìn)行insertOrUpdate操作的附加字段。 

import lombok.Data;
@Data
public class Sheet {
 
    /**
     * 主鍵
     */
    private String id;
    /**
     * 客戶姓名
     */
    private String customerName;
    /**
     * 。。。省略其他字段
     */
 
    /**
     * 該字段為非業(yè)務(wù)字段。Mybatis配置文件需要要到該字段,方便進(jìn)行insertOrUpdate操作
     */
    private int count;
}

Mybatis的mapper.xml配置文件代碼如下。

代碼含義:先執(zhí)行selectKey語(yǔ)句,把結(jié)果賦值給Sheet類的count屬性。

  • 如果count大于0,表示記錄已存在,則進(jìn)行update操作。
  • 如果count等于0,表示沒有記錄,則進(jìn)行insert操作。
<update id="insertOrUpdate" parameterType="Sheet" >
        <selectKey keyProperty="count" resultType="int" order="BEFORE">
            select count(1) from sheet where ID= #{id}
        </selectKey>
        <if test="count > 0">
            update sheet 
            <set>
                <if test="customerName != null and customerName != ''">
                    CUSTOMER_NAME= #{customerName},
                </if>
            </set>
            where ID = #{id}
        </if>
        <if test="count==0">
            insert into sheet
            <trim prefix="(" suffix=")" suffixOverrides=",">
                ID,
                <if test="customerName != null and customerName != ''">
                    CUSTOMER_NAME,
                </if>
            </trim>
            <trim prefix="values (" suffix=")" suffixOverrides=",">
                #{id},
                <if test="customerName != null and customerName != ''">
                    #{customerName},
                </if>
            </trim>
        </if>
    </update>

selectKey標(biāo)簽可以給update標(biāo)簽中的parameterType屬性(model類)對(duì)應(yīng)的對(duì)象設(shè)置屬性值。selectKey標(biāo)簽的屬性描述:

  • keyProperty:selectKey 語(yǔ)句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性。此處對(duì)應(yīng)的就是Sheet類的count屬性。
  • resultType:結(jié)果的類型,此處為屬性count的類型。
  • order:可以被設(shè)置為 BEFORE 或 AFTER。BEFORE表示先執(zhí)行selectKey語(yǔ)句,后執(zhí)行update語(yǔ)句;AFTER表示先執(zhí)行update語(yǔ)句,后執(zhí)行selectKey語(yǔ)句。

Mybatis學(xué)習(xí)筆記:InsertOrUpdate

環(huán)境

  • Intellij IDEA : 2021.3
  • Mysql:8+
  • java:1.8+

前言

以前使用mongodb、JOOQ組件的時(shí)候都是有insertOrUpdate的功能,現(xiàn)在使用mybatis似乎沒有提供這種功能。

最近研究了,這個(gè)功能其實(shí)是mysql提供的,利用的是duplicate key update;

假設(shè),我們有這么一張表: 

CREATE TABLE `relation` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `name` varchar(64) NOT NULL DEFAULT '' COMMENT '名稱',
  `relation_id` varchar(64) NOT NULL DEFAULT '' COMMENT '關(guān)聯(lián)id',
  `type` int(11) NOT NULL DEFAULT '0' COMMENT '0:默認(rèn)',
  `is_delete` tinyint(4) NOT NULL DEFAULT '0' COMMENT ' 狀態(tài)值',
  `create_at` varchar(64) NOT NULL DEFAULT '' COMMENT '創(chuàng)建人',
  `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  `update_at` varchar(64) NOT NULL DEFAULT '' COMMENT '更新人',
  `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新人',
  PRIMARY KEY (`id`),
  UNIQUE KEY `ix_relation_id_type` (`relation_id`,`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

注意: ix_relation_id_type:唯一索引

Dao

@Mapper
public interface FlowModelMapper {
? ? void insertOrUpdate(List<FlowModel> flowModel);
}

Mapper XML文件

<insert id="insertOrUpdate">
    insert into flow_model(name, relation_id, type, is_delete,create_at,update_at)
    values
    <foreach collection="list" item="p" index="index" separator=",">
        (
        #{p.name},
        #{p.relationId},
        #{p.type},
        #{p.isDelete},
        #{p.createAt},
        #{p.updateAt}
        )
    </foreach>
    on duplicate key update
    name=values(name),
    update_at=values(update_at)
</insert>

說(shuō)明:

  • on duplicate key update這個(gè)是非常關(guān)鍵的地方,需要有唯一鍵和主鍵。
  • on duplicate key update后面跟著的name=values(name)算是一個(gè)固定寫法,作用:動(dòng)態(tài)的傳入要修改的值。

在MySQL 8.0.20之后,VALUES()在mysql未來(lái)的版本會(huì)被刪除。

官方建議,使用列別名的方式來(lái)寫:

<insert id="insertOrUpdate">
    insert into flow_model(name, relation_id, type, is_delete,create_at,update_at)
    values
    <foreach collection="list" item="p" index="index" separator=",">
        (
        #{p.name},
        #{p.relationId},
        #{p.type},
        #{p.isDelete},
        #{p.createAt},
        #{p.updateAt}
        )
    </foreach>
    AS fm
    on duplicate key update
    name=fm.name,
    update_at=fm.update_at
</insert>

行別名

insert into …values

語(yǔ)法:insert into ...values(...) AS 行別名 ON DUPLICATE KEY UPDATE 使用行別名。

例如:下面的 new就是行別名。

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
? ON DUPLICATE KEY UPDATE c = new.a+new.b;

列別名

或者是:insert into ...values(...) AS 行別名(列別名,列別名,列別名) ON DUPLICATE KEY UPDATE 使用別名

下面的m,n,p是隨便取的列別名

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)
? ON DUPLICATE KEY UPDATE c = m+n;

注意:

當(dāng)使用列別名時(shí),必須在VALUES子句后面使用行別名,即使在后面的子句中不使用行別名。

除了insert into … values 場(chǎng)景,insert into …set場(chǎng)景也適用。

語(yǔ)法和上面是一樣的:

INSERT INTO t1 SET a=1,b=2,c=3 AS new
? ON DUPLICATE KEY UPDATE c = new.a+new.b;
INSERT INTO t1 SET a=1,b=2,c=3 AS new(m,n,p)
? ON DUPLICATE KEY UPDATE c = m+n;

主鍵和唯一索引 

現(xiàn)在假設(shè)我們有這些索引:

唯一索引:biz_id、name、code

主鍵:id

insert into template_url(id,name, code, url, scope, description,
    biz_id, create_by, create_user_id, update_by, update_user_id)
    values
      (
	1,'yutao','yutao','www.baidu.com','yutao','yutao',0,'yutao',0,'yutao',0
      )
    ON DUPLICATE KEY UPDATE
	name=values(name),
    description=values(description),
    url=values(url),
    scope=values(scope),
    update_by=values(update_by),
    update_user_id=values(update_user_id)

主鍵沖突

假設(shè)這時(shí),主鍵沖突,那么MySQL就會(huì)接著判斷是否 唯一索引沖突:

① 唯一索引不沖突,那么久執(zhí)行更新

② 唯一索引沖突,就會(huì)報(bào)錯(cuò):

1062 - Duplicate entry '0-yutao-yutao111' for key 'template_url.uk_biz_id_code_name', Time: 0.004000s

編輯時(shí),唯一索引的字段不要修改

小結(jié)一下:insertOrUpdate的實(shí)現(xiàn)是基于mysql的on duplicate key update 來(lái)實(shí)現(xiàn)的。

使用ON DUPLICATE KEY UPDATE,如果行作為新行插入,則每行受影響的行值為1。如果更新現(xiàn)有行,則每行受影響的行值為2;如果將現(xiàn)有行設(shè)置為其當(dāng)前值,則每行受影響的行值為0(可以通過配置,使其受影響的行值為1)。

官方地址:

13.2.6.2 INSERT … ON DUPLICATE KEY UPDATE Statement

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持html5模板網(wǎng)。

【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

主站蜘蛛池模板: 亚洲精品久久久久久久不卡四虎 | 青草青草久热精品视频在线观看 | 久久久久国产精品 | 91av视频在线免费观看 | 无人区国产成人久久三区 | 亚洲免费高清 | 天堂亚洲| 亚洲成人精品在线 | 欧美视频三区 | 中文字幕一区二区三区乱码图片 | 色综合久久天天综合网 | 亚洲一区二区av | 国产午夜精品一区二区三区四区 | av中文字幕在线观看 | 国产日韩精品久久 | 人人玩人人添人人澡欧美 | 青青草视频免费观看 | 国产剧情一区二区三区 | 91精品国产一区二区三区动漫 | 欧美一级网站 | 麻豆精品国产91久久久久久 | 日韩一级欧美一级 | 三级黄视频在线观看 | 天天插天天操 | 中文字幕一区二区三区日韩精品 | 99福利视频 | 国产日韩精品一区二区 | 久久伊人操 | 求毛片 | 亚洲欧美日韩中文在线 | 久久久久综合 | 国产精品电影网 | 久久精品国产久精国产 | 美女久久视频 | 97视频在线观看网站 | 欧美aaa一级片 | 99reav| 在线观看av网站永久 | 美女视频一区二区三区 | 视频在线一区二区 | 在线毛片网 |