本文主要研究一下gorm的OnConflict

OnConflict

gorm.io/gorm@v1.20.11/clause/on_conflict.go

type OnConflict struct {Columns      []ColumnWhere        WhereOnConstraint stringDoNothing    boolDoUpdates    SetUpdateAll    bool
}func (OnConflict) Name() string {return "ON CONFLICT"
}// Build build onConflict clause
func (onConflict OnConflict) Build(builder Builder) {if len(onConflict.Columns) > 0 {builder.WriteByte('(')for idx, column := range onConflict.Columns {if idx > 0 {builder.WriteByte(',')}builder.WriteQuoted(column)}builder.WriteString(`) `)}if len(onConflict.Where.Exprs) > 0 {builder.WriteString("WHERE ")onConflict.Where.Build(builder)builder.WriteByte(' ')}if onConflict.OnConstraint != "" {builder.WriteString("ON CONSTRAINT ")builder.WriteString(onConflict.OnConstraint)builder.WriteByte(' ')}if onConflict.DoNothing {builder.WriteString("DO NOTHING")} else {builder.WriteString("DO UPDATE SET ")onConflict.DoUpdates.Build(builder)}
}// MergeClause merge onConflict clauses
func (onConflict OnConflict) MergeClause(clause *Clause) {clause.Expression = onConflict
}

OnConflict定义了Columns、Where、OnConstraint、DoNothing、DoUpdates、UpdateAll属性;Build方法会根据这些属性拼装sql,如果是DoNothing则追加DO NOTHING,否则追加DO UPDATE SET

Expression

gorm.io/gorm@v1.20.11/clause/set.go

type Set []Assignmenttype Assignment struct {Column ColumnValue  interface{}
}func (set Set) Name() string {return "SET"
}func (set Set) Build(builder Builder) {if len(set) > 0 {for idx, assignment := range set {if idx > 0 {builder.WriteByte(',')}builder.WriteQuoted(assignment.Column)builder.WriteByte('=')builder.AddVar(builder, assignment.Value)}} else {builder.WriteQuoted(PrimaryColumn)builder.WriteByte('=')builder.WriteQuoted(PrimaryColumn)}
}// MergeClause merge assignments clauses
func (set Set) MergeClause(clause *Clause) {copiedAssignments := make([]Assignment, len(set))copy(copiedAssignments, set)clause.Expression = Set(copiedAssignments)
}func Assignments(values map[string]interface{}) Set {keys := make([]string, 0, len(values))for key := range values {keys = append(keys, key)}sort.Strings(keys)assignments := make([]Assignment, len(keys))for idx, key := range keys {assignments[idx] = Assignment{Column: Column{Name: key}, Value: values[key]}}return assignments
}func AssignmentColumns(values []string) Set {assignments := make([]Assignment, len(values))for idx, value := range values {assignments[idx] = Assignment{Column: Column{Name: value}, Value: Column{Table: "excluded", Name: value}}}return assignments
}

的DoUpdates属性是Set类型,Set类型实际是Assignment数组;其Build方法会组装assignment的sql

实例

func onConflictDemo(db *gorm.DB) {entities := []DemoEntity{{Model: gorm.Model{ID: 1},Name:  "coco",},{Model: gorm.Model{ID: 2},Name:  "bear",},}result := db.Debug().Create(&entities)b, _ := json.Marshal(entities)log.Println("data:", string(b))log.Println("result.RowsAffected:", result.RowsAffected, "result.Error:", result.Error)if err := db.Debug().Clauses(clause.OnConflict{DoNothing: true}).Create(&entities).Error; err != nil {panic(err)}
}

输出

2021/01/17 20:03:31 /demo.go:53 UNIQUE constraint failed: demo_entities.id
[0.487ms] [rows:0] INSERT INTO `demo_entities` (`created_at`,`updated_at`,`deleted_at`,`name`,`id`) VALUES ("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"coco",1),("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"bear",2)
2021/01/17 20:03:31 data: [{"ID":1,"CreatedAt":"2021-01-17T20:03:31.71143+08:00","UpdatedAt":"2021-01-17T20:03:31.71143+08:00","DeletedAt":null,"Name":"coco"},{"ID":2,"CreatedAt":"2021-01-17T20:03:31.71143+08:00","UpdatedAt":"2021-01-17T20:03:31.71143+08:00","DeletedAt":null,"Name":"bear"}]
2021/01/17 20:03:31 result.RowsAffected: 0 result.Error: UNIQUE constraint failed: demo_entities.id2021/01/17 20:03:31 /demo.go:58
[0.123ms] [rows:0] INSERT INTO `demo_entities` (`created_at`,`updated_at`,`deleted_at`,`name`,`id`) VALUES ("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"coco",1),("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"bear",2) ON CONFLICT DO NOTHING

小结

gorm的OnConflict定义了Columns、Where、OnConstraint、DoNothing、DoUpdates、UpdateAll属性;Build方法会根据这些属性拼装sql,如果是DoNothing则追加DO NOTHING,否则追加DO UPDATE SET

doc

  • gorm

聊聊gorm的OnConflict相关推荐

  1. GORM CRUD 10 分钟快速上手

    文章目录 1.ORM 是什么 2.GORM 是什么 3.安装 4.连接 DB 5.创建数据表 6.增加(Create) 7.查询(Read) 按照主键查询 IN 查询 AND 条件 OR 条件 Gro ...

  2. Gorm之gorm.io/gorm源码

    文章目录 Gorm之gorm.io/gorm源码 1.gorm.Open函数 2.gorm.Dialector接口 3.gorm.Config结构体 4.gorm.DB结构体 4.1gorm.DB结构 ...

  3. GORM 基础 -- Gen

    https://gorm.io/gen/ github 1.GEN Guides GEN:友好和更安全的代码生成 1.1 概述 来自动态原始SQL的惯用和可重用API 100%类型安全的DAO API ...

  4. Gorm -- 添加记录

    文章目录 添加单条记录 直接添加模型对象 赋予默认值方法一: gorm 标签 赋予默认值方法二: 设置钩子方法(Hooks) 指定字段插入 插入时忽略某些字段 插入时禁止使用钩子方法 添加多条记录 通 ...

  5. golangORM框架gorm详解(超详细)

    ORM简介 对象关系映射模式(object relational Mapping)是为了解决面向对象和关系型数据库存在的互不匹配的问题,简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程 ...

  6. 面向对象设计原则_聊聊面向对象的6大设计原则

    程序员都知道编程有 3 大类:面向过程.面向对象.面向函数.面向对象是被讨论的最多的,个人认为,这是因为 Java 之类的编程语言有强大的用户基础,本质还是因为比较符合人的直觉. 说到面向对象,大家可 ...

  7. python邮件发送哪个好_最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 邮件,作为最正式规范的沟通方式,在日常办公过程中经常被用到 我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本.富文本.HTML 等格式的邮件 本文将聊聊利用 Python ...

  8. 今天聊聊分布式锁 No.86

    好了切入正题,一直在工作中会聊到很多锁的问题,今天跟大家一起闲聊一下,究竟什么是锁,为什么需要锁,以及分布式的情况下,怎么设计和实现锁. 什么是锁? 明·魏禧<大铁椎传>上是这样解释的: ...

  9. 聊聊找工作中的项目经验问题(推荐系统和智能问答)

    在求职过程中有这么一句话叫做"金九银十",也就是说,很多时候,求职的黄金时期就是在九月份和十月份,这两个月份中企业需求是最多的,求职的成功率也是最高的.但是随着AI方面的人才越来越 ...

最新文章

  1. 如何有效防止域名被电信服务商劫持(电信114弹窗广告)
  2. pkg-config简介 pkgconfig
  3. C# 3.0新特性系列(1):隐含类型局部变量
  4. Delphi多媒体设计之TMediaPlayer组件(一)
  5. MongoDB最新4.2.7版本三分片集群修改IP实操演练
  6. Vmware工作笔记-通过光驱位与虚拟机(Vmware)共享数据【含iso制作】
  7. MySQL主从复制遇到的问题以及如何解决
  8. python基础编程语法-1.Python基础语法
  9. 鼎捷T100标准接口调用
  10. 购买计算机相关配件的会计分录,购买电脑配件自己组装电脑怎么写会计分录
  11. Excel数据分列大法总结
  12. 解决SQLServer复制到Excel中内容换行问题
  13. 几个实用的生活服务网站和APP
  14. 烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一 个小时十五分钟呢?(微软面试题)
  15. java.lang.NoSuchMethodError: org.springframework.http.MediaType.getCharSet()Ljava/nio/charset/Charse
  16. python ogr_GDAL/OGR概述
  17. 短信验证码安全常见逻辑漏洞
  18. js监听html页面大小变化,js实时获取浏览器窗口大小
  19. 2_XMR的技术概念
  20. 从Solr卡顿到G1垃圾回收

热门文章

  1. 写一篇 500 字的文章,主题关于 18 世纪哲学家大卫 • 休谟和恐怖悖论,即研究人们是如何从他们害怕的东西中获得乐趣的...
  2. 擦地机器人排行榜_扫地机器人十大排行榜
  3. 商家使用会员卡有什么好处?手机app即可办理实体会员卡!
  4. 由MAVEN入手浅谈项目构建与管理
  5. Pandas常用方法一
  6. 安卓 jni 开发错误 undefined reference to __android_log_print
  7. 拿到一个vue+webpack项目,该如何去看
  8. 时空图神经网络(ST-GNN)
  9. python+vue校园足球联赛管理系统django源码
  10. 大众点评的大数据实践