Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊gorm的OnConflict

聊聊gorm的OnConflict

原创
作者头像
code4it
修改于 2021-01-18 06:27:43
修改于 2021-01-18 06:27:43
3.4K00
代码可运行
举报
文章被收录于专栏:码匠的流水账码匠的流水账
运行总次数:0
代码可运行

本文主要研究一下gorm的OnConflict

OnConflict

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type OnConflict struct {
    Columns      []Column
    Where        Where
    OnConstraint string
    DoNothing    bool
    DoUpdates    Set
    UpdateAll    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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Set []Assignment

type Assignment struct {
    Column Column
    Value  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

实例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)
    }
}

输出

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.id

2021/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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
聊聊gorm的OnConflict
gorm.io/gorm@v1.20.11/clause/on_conflict.go
code4it
2021/01/25
6080
聊聊gorm的Locking
Locking定义了Strength、Table、Options属性;Build方法先追加Strength,后面根据Table、Options属性追加语句;Strength支持SHARE、UPDATE;Options支持NOWAIT。
code4it
2021/01/18
5500
聊聊gorm的Locking
聊聊gorm的GroupBy
gorm的GroupBy定义了Columns和Having属性,其Build方法遍历Columns,最后针对Having在拼接Having子句。
code4it
2021/01/19
9750
聊聊gorm的GroupBy
聊聊gorm的CreateInBatches
gorm.io/gorm@v1.20.11/callbacks/transaction.go
code4it
2021/01/16
1K0
聊聊gorm的CreateInBatches
Gorm实战,轻松掌握数据库增删改查技巧!
CRUD通常指数据库的增删改查操作,本文详细介绍了如何使用GORM实现创建、查询、更新和删除操作。
贾维斯Echo
2024/01/12
3.7K0
聊聊gorm的Model
gorm.io/gorm@v1.20.10/callbacks/create.go
code4it
2021/01/08
4810
聊聊gorm的Model
GORM CRUD 10 分钟快速上手
ORM(Object Relational Mapping),中文名为对象关系映射。
恋喵大鲤鱼
2023/10/12
8630
聊聊gorm的Unscoped
gorm.io/gorm@v1.20.11/callbacks/delete.go
code4it
2021/01/15
1.3K0
聊聊gorm的Unscoped
聊聊gorm的DeletedAt
gorm.io/gorm@v1.20.10/schema/interfaces.go
code4it
2021/01/09
9570
聊聊gorm的DeletedAt
学习gorm系列五:gorm中的核心数据结构
今天咱们一起来学习下gorm中的几个核心数据结构。通过了解gorm底层的数据结构,能够让我们了解gorm底层的实现,以便更好的使用gorm。
Go学堂
2023/11/01
5410
学习gorm系列五:gorm中的核心数据结构
Gorm 实践指南
GORM 默认的数据更新、创建都在事务中,如无必要,可以关闭默认的事务,获得更大的性能提升, 事务的全局性或者临时关闭,即使在关闭默认事务,仍然可以通过方法 Begin, Transactions 方法开启事务。
王小明_HIT
2021/07/05
2.3K0
聊聊gorm的logger
gorm的logger提供了Interface接口,可以自己实现并全局设置或者在session级别设置;gorm默认的logger实现了logger.Interface接口定义的LogMode、Info、Warn、Error、Trace方法。
code4it
2021/01/10
7330
聊聊gorm的logger
一文入门gorm和xorm的基本操作(CRUD)
GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server
用户6297767
2023/11/21
7170
golang源码分析:gorm
gorm使用很简洁,首先打开数据库连接(Open initialize a new db connection, need to import driver first)
golangLeetcode
2022/08/03
2.6K0
Go gorm
在后端开发上,通常都要与资料库做操作(新增、修改、删除、查找),后端会撰写 SQL 语句,并且透过一些工具或套件(例如:pymysql)向 SQL 资料库来做沟通。而撰写原生 SQL 的缺点为:
f1sh
2024/07/29
3280
GORM V2 写操作
在项目开发中,数据库写操作包含新增、删除和修改,使用 GORM V2 可以更加安全和便捷进行写操作。
frank.
2020/09/18
2.8K0
从零实现ORM框架GeoORM-记录新增和查询-03
本系列源码: https://gitee.com/DaHuYuXiXi/geo-orm
大忽悠爱学习
2022/09/28
1.1K0
Go语言 orm库之gorm
GORM是一个比较流行且功能齐全的orm库,主要有以下特性 全功能 ORM 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承) Create,Save,Update,Delete,Find 中钩子方法 支持 Preload、Joins 的预加载 事务,嵌套事务,Save Point,Rollback To Saved Point Context,预编译模式,DryRun 模式 批量插入,FindInBatches,Find/Create with Ma
孤烟
2020/12/07
1.2K0
聊聊dubbo-go-proxy的AccessLogFilter
dubbo-go-proxy/pkg/filter/accesslog/access_log.go
code4it
2021/02/02
3030
聊聊dubbo-go-proxy的AccessLogFilter
Gorm框架学习---CRUD接口之创建
要有效地插入大量记录,请将一个 slice 传递给 Create 方法。 GORM 将生成单独一条SQL语句来插入所有数据,并回填主键的值,钩子方法也会被调用。
大忽悠爱学习
2022/09/23
1.3K0
Gorm框架学习---CRUD接口之创建
相关推荐
聊聊gorm的OnConflict
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验