pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

Mybatis如何實現InsertOrUpdate功能

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

實現InsertOrUpdate功能

需求

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

實現

每次操作數據庫之前,先根據id查詢有沒有記錄,有則進行update操作,沒有則進行insert操作。

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

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

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

代碼含義:先執行selectKey語句,把結果賦值給Sheet類的count屬性。

  • 如果count大于0,表示記錄已存在,則進行update操作。
  • 如果count等于0,表示沒有記錄,則進行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標簽可以給update標簽中的parameterType屬性(model類)對應的對象設置屬性值。selectKey標簽的屬性描述:

  • keyProperty:selectKey 語句結果應該被設置的目標屬性。此處對應的就是Sheet類的count屬性。
  • resultType:結果的類型,此處為屬性count的類型。
  • order:可以被設置為 BEFORE 或 AFTER。BEFORE表示先執行selectKey語句,后執行update語句;AFTER表示先執行update語句,后執行selectKey語句。

Mybatis學習筆記:InsertOrUpdate

環境

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

前言

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

最近研究了,這個功能其實是mysql提供的,利用的是duplicate key update;

假設,我們有這么一張表: 

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 '關聯id',
  `type` int(11) NOT NULL DEFAULT '0' COMMENT '0:默認',
  `is_delete` tinyint(4) NOT NULL DEFAULT '0' COMMENT ' 狀態值',
  `create_at` varchar(64) NOT NULL DEFAULT '' COMMENT '創建人',
  `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `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>

說明:

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

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

官方建議,使用列別名的方式來寫:

<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

語法: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;

注意:

當使用列別名時,必須在VALUES子句后面使用行別名,即使在后面的子句中不使用行別名。

除了insert into … values 場景,insert into …set場景也適用。

語法和上面是一樣的:

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;

主鍵和唯一索引 

現在假設我們有這些索引:

唯一索引: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)

主鍵沖突

假設這時,主鍵沖突,那么MySQL就會接著判斷是否 唯一索引沖突:

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

② 唯一索引沖突,就會報錯:

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

編輯時,唯一索引的字段不要修改

小結一下:insertOrUpdate的實現是基于mysql的on duplicate key update 來實現的。

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

官方地址:

13.2.6.2 INSERT … ON DUPLICATE KEY UPDATE Statement

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持html5模板網。

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

相關文檔推薦

主站蜘蛛池模板: 上海宿田自动化设备有限公司-双面/平面/单面贴标机 | (中山|佛山|江门)环氧地坪漆,停车场地板漆,车库地板漆,聚氨酯地板漆-中山永旺地坪漆厂家 | 聚氨酯保温钢管_聚氨酯直埋保温管道_聚氨酯发泡保温管厂家-沧州万荣防腐保温管道有限公司 | 塑胶跑道_学校塑胶跑道_塑胶球场_运动场材料厂家_中国塑胶跑道十大生产厂家_混合型塑胶跑道_透气型塑胶跑道-广东绿晨体育设施有限公司 | Eiafans.com_环评爱好者 环评网|环评论坛|环评报告公示网|竣工环保验收公示网|环保验收报告公示网|环保自主验收公示|环评公示网|环保公示网|注册环评工程师|环境影响评价|环评师|规划环评|环评报告|环评考试网|环评论坛 - Powered by Discuz! | 玻璃钢格栅盖板|玻璃钢盖板|玻璃钢格栅板|树篦子-长沙川皖玻璃钢制品有限公司 | 恒温恒湿试验箱_高低温试验箱_恒温恒湿箱-东莞市高天试验设备有限公司 | 七维官网-水性工业漆_轨道交通涂料_钢结构漆 | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) | 万家财经_财经新闻_在线财经资讯网| 泰来华顿液氮罐,美国MVE液氮罐,自增压液氮罐,定制液氮生物容器,进口杜瓦瓶-上海京灿精密机械有限公司 | 北京晚会活动策划|北京节目录制后期剪辑|北京演播厅出租租赁-北京龙视星光文化传媒有限公司 | 泡沫消防车_水罐消防车_湖北江南专用特种汽车有限公司 | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 冷水机-冰水机-冷冻机-冷风机-本森智能装备(深圳)有限公司 | 杭州货架订做_组合货架公司_货位式货架_贯通式_重型仓储_工厂货架_货架销售厂家_杭州永诚货架有限公司 | CCE素质教育博览会 | CCE素博会 | 教育展 | 美育展 | 科教展 | 素质教育展 | 实验室隔膜泵-无油防腐蚀隔膜泵-耐腐蚀隔膜真空泵-杭州景程仪器 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 脱硫搅拌器厂家-淄博友胜不锈钢搅拌器厂家 | 脉冲除尘器,除尘器厂家-淄博机械| 全自动真空上料机_粉末真空上料机_气动真空上料机-南京奥威环保科技设备有限公司 | 门禁卡_智能IC卡_滴胶卡制作_硅胶腕带-卡立方rfid定制厂家 | 液氮罐(生物液氮罐)百科-无锡爱思科 | 破碎机锤头_耐磨锤头_合金锤头-鼎成机械一站式耐磨铸件定制服务 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 网站建设-网站制作-网站设计-网站开发定制公司-网站SEO优化推广-咏熠软件 | 上海办公室装修公司_办公室设计_直营办公装修-羚志悦装 | 上海佳武自动化科技有限公司 | 砂石生产线_石料生产线设备_制砂生产线设备价格_生产厂家-河南中誉鼎力智能装备有限公司 | 浙江美尔凯特智能厨卫股份有限公司| 同学聚会纪念册制作_毕业相册制作-成都顺时针宣传画册设计公司 | 固诺家居-全屋定制十大品牌_整体衣柜木门橱柜招商加盟 | 政府园区专业委托招商平台_助力企业选址项目快速落地_东方龙商务集团 | 哈尔滨治「失眠/抑郁/焦虑症/精神心理」专科医院排行榜-京科脑康免费咨询 一对一诊疗 | 中国玩具展_玩具展|幼教用品展|幼教展|幼教装备展 | 专业音响设备_舞台音响设备_会议音响工程-首选深圳一禾科技 | 球磨机,节能球磨机价格,水泥球磨机厂家,粉煤灰球磨机-吉宏机械制造有限公司 | 高精度电阻回路测试仪-回路直流电阻测试仪-武汉特高压电力科技有限公司 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | 气弹簧定制-气动杆-可控气弹簧-不锈钢阻尼器-工业气弹簧-可调节气弹簧厂家-常州巨腾气弹簧供应商 | 西装定制/做厂家/公司_西装订做/制价格/费用-北京圣达信西装 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 |