亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識(shí)庫 > Golang 使用gorm添加數(shù)據(jù)庫排他鎖,for update

Golang 使用gorm添加數(shù)據(jù)庫排他鎖,for update

熱門標(biāo)簽:地圖標(biāo)注免費(fèi)定制店 仙桃400電話辦理 湛江crm外呼系統(tǒng)排名 宿遷便宜外呼系統(tǒng)代理商 鄭州智能語音電銷機(jī)器人價(jià)格 重慶慶云企業(yè)400電話到哪申請(qǐng) 寧波語音外呼系統(tǒng)公司 上海極信防封電銷卡價(jià)格 不封卡外呼系統(tǒng)

適用于先讀后更新的數(shù)據(jù)競爭場景,且應(yīng)該將加鎖操作放到事務(wù)中,防止鎖被自動(dòng)釋放,原因參考mysql doc

func UpdateUser(db *gorm.DB, id int64) error {
  tx := db.Begin()
  defer func() {
    if r := recover(); r != nil {
      tx.Rollback()
    }
  }()
  if err := tx.Error; err != nil {
    return err
  }
  user := User{}
  // 鎖住指定 id 的 User 記錄
  if err := tx.Set("gorm:query_option", "FOR UPDATE").First(user, id).Error; err != nil {
    tx.Rollback()
    return err
  }
  // 更新操作...
  // commit事務(wù),釋放鎖
  if err := tx.Commit().Error; err != nil {
    return err
  }
  return nil
}

sync.Mutex解法(效率較低):

var lock sync.Mutex
func UpdateUser(db *gorm.DB, id int64) error {
  lock.Lock()
  // 數(shù)據(jù)庫操作...
  lock.Unlock()
  return nil
}

參考

doc

補(bǔ)充:Golang數(shù)據(jù)庫編程之GORM模型定義與數(shù)據(jù)庫遷移

在開發(fā)應(yīng)用程序時(shí),一般而言,我們是先設(shè)計(jì)好數(shù)據(jù)表,再使用開發(fā)語言建立對(duì)應(yīng)的數(shù)據(jù)模型,不過,我們今天要講的是一個(gè)逆向操作的過程,即如何通定義GORM框架的數(shù)據(jù)模型,然后再通過執(zhí)行GROM框架編寫的應(yīng)用程序,用定義好數(shù)據(jù)模型在數(shù)據(jù)庫中創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)表。

因此需要先講講怎么定義GORM的數(shù)據(jù)模型。

模型定義

一般來說,我們說GROM的模型定義,是指定義代表一個(gè)數(shù)據(jù)表的結(jié)構(gòu)體(struct),然后我們可以使用GROM框架可以將結(jié)構(gòu)體映射為相對(duì)應(yīng)的關(guān)系數(shù)據(jù)庫的數(shù)據(jù)表,或者查詢數(shù)據(jù)表中的數(shù)據(jù)來填充結(jié)構(gòu)體,如下所示,我們定義了一個(gè)名為Post的結(jié)構(gòu)體。

type Post struct {
PostId int
Uid int
Title string
Content string
Type int
CreatedAt time.Time
UpdatedAt time.Time
}

創(chuàng)建好一個(gè)結(jié)構(gòu)體只是第一步,不過先不著急要怎么去創(chuàng)建數(shù)據(jù)表,我們要先了解一下結(jié)構(gòu)體與數(shù)據(jù)表之間的映射規(guī)則,主要有以下幾點(diǎn):

Struct tags

我們知道,Go語言的結(jié)構(gòu)體支持使用tags為結(jié)構(gòu)體的每個(gè)字段擴(kuò)展額外的信息,如使用標(biāo)準(zhǔn)庫encoding/json包進(jìn)行JSON編碼時(shí),便可以使用tags進(jìn)行編碼額外信息的擴(kuò)展。

GROM框架有自己的一個(gè)tags約定,如下所示:

Column 指定列名

Type 指定列數(shù)據(jù)類型

Size 指定列大小, 默認(rèn)值255

PRIMARY_KEY 將列指定為主鍵

UNIQUE 將列指定為唯一

DEFAULT 指定列默認(rèn)值

PRECISION 指定列精度

NOT NULL 將列指定為非 NULL

AUTO_INCREMENT 指定列是否為自增類型

INDEX 創(chuàng)建具有或不帶名稱的索引, 如果多個(gè)索引同名則創(chuàng)建復(fù)合索引

UNIQUE_INDEX 和 INDEX 類似,只不過創(chuàng)建的是唯一索引

EMBEDDED 將結(jié)構(gòu)設(shè)置為嵌入

EMBEDDED_PREFIX 設(shè)置嵌入結(jié)構(gòu)的前綴

- 忽略此字段

GROM還支持一些關(guān)聯(lián)數(shù)據(jù)表的tags約定,有機(jī)會(huì)我講講GROM數(shù)據(jù)表關(guān)聯(lián)的時(shí)候,會(huì)說到的。

上面列出的GORM支持的tags,方便我們定制結(jié)構(gòu)體字段到數(shù)據(jù)表字段之間的映射規(guī)則,下面的代碼,我們給Post結(jié)構(gòu)體定制一些tags擴(kuò)展,如下:

type Post struct {
PostId int `gorm:"primary_key;auto_increment"`
Uid int `gorm:"type:int;not null"`
Title string `gorm:"type:varchar(255);not null"`
Content string `gorm:"type:text;not null"`
Type uint8 `gorm:"type:tinyint;default 1;not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt time.Time
}

從上面的例子我們可以看出GORM為數(shù)據(jù)模型的字段定義tags的格式,每個(gè)字段可以用多個(gè)類型的tags信息,不同的tag之間用分號(hào)分隔。

慣例

除了上面講的tags定義了字段之間的映射規(guī)則外,Go將結(jié)構(gòu)體映射為關(guān)系型數(shù)據(jù)表時(shí),還有自己的一套慣例,或稱為約定,主要有以下幾點(diǎn):

主鍵

GROM的約定中,一般將數(shù)據(jù)模型中的ID字段映射為數(shù)據(jù)表的主鍵,如下面定義的TestModel,ID為主鍵,TestModel的ID的數(shù)據(jù)類型為string,如果ID的數(shù)據(jù)類型為int,則GROM還會(huì)為該設(shè)置AUTO_INCREMENT,使用ID成為自增主鍵。

type TestModel struct{
ID int
Name string
}

當(dāng)然,我們也可以自定義主鍵字段的名稱,如上面的Post結(jié)構(gòu)體,我們?cè)O(shè)置了PostId字段為主鍵,如果我們定義了其他字段為主鍵,那么,就算結(jié)構(gòu)體中仍有ID字段,GROM框架也不會(huì)把ID字段當(dāng)作主鍵了。

type Post struct {
ID int
PostId int `gorm:"primary_key;auto_increment"`
Uid int `gorm:"type:int;not null"`
Title string `gorm:"type:varchar(255);not null"`
Content string `gorm:"type:text;not null"`
Type uint8 `gorm:"type:tinyint;default 1;not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt time.Time
}

所以,我們?cè)赑ost結(jié)構(gòu)體中加一個(gè)ID字段,PostId字段仍是主鍵,下面是在數(shù)據(jù)中使用desc posts語句打印出來的結(jié)果:

數(shù)據(jù)表映射規(guī)則

當(dāng)我們使用結(jié)構(gòu)體創(chuàng)建數(shù)據(jù)表時(shí),數(shù)據(jù)表的名稱默認(rèn)為結(jié)構(gòu)體的小寫復(fù)數(shù)形式,如結(jié)構(gòu)體Post對(duì)應(yīng)的數(shù)據(jù)表名稱為posts,當(dāng)然我們也可以自己指定結(jié)構(gòu)體對(duì)應(yīng)的數(shù)據(jù)表名稱,而不是用默認(rèn)的。

為結(jié)構(gòu)體加上TableName()方法,通過這個(gè)方法可以返回自定義的數(shù)據(jù)表名,如下:

//指定Post結(jié)構(gòu)體對(duì)應(yīng)的數(shù)據(jù)表為my_posts
func (p Post) TableName() string{
return "my_posts"
}

數(shù)據(jù)表前綴

除了指定數(shù)據(jù)表名外,我們也可以重寫gorm.DefaultTableNameHandler這個(gè)變量,這樣可以為所有數(shù)據(jù)表指定統(tǒng)一的數(shù)據(jù)表前綴,如下:

gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "tb_" + defaultTableName;
}

這樣的話,通過結(jié)構(gòu)體Post創(chuàng)建的數(shù)據(jù)表名稱則為tb_posts。

字段映射規(guī)則

結(jié)構(gòu)體到數(shù)據(jù)表的名稱映射規(guī)則為結(jié)構(gòu)體名稱的復(fù)數(shù),而結(jié)構(gòu)體的字段到數(shù)據(jù)表字段的默認(rèn)映射規(guī)則是用下劃線分隔每個(gè)大寫字母開頭的單詞,如下:

type Prize struct {
ID int
PrizeName string
}

上面的結(jié)構(gòu)體Prize中的PrizeName字段對(duì)應(yīng)的數(shù)據(jù)表為prize_name,但我們把PrizeName改為Prizename時(shí),則對(duì)應(yīng)的數(shù)據(jù)表字段名稱為prizename,這是為因?yàn)橹环指舸髮懽侄伍_頭的單詞。

當(dāng)然,我們也可以為結(jié)構(gòu)體的某個(gè)字段定義tags擴(kuò)展信息,這樣結(jié)構(gòu)體字段到數(shù)據(jù)表字段的映規(guī)則就在tags中定義。

時(shí)間點(diǎn)追蹤

前面我們說過,如果結(jié)構(gòu)體中有名稱為ID字段,則GORM框架會(huì)把該字段作為數(shù)據(jù)表的主鍵,除此之外,如果結(jié)構(gòu)體中有CreatedAt,UpdatedAt,DeletedAt這幾個(gè)字段的話,則GROM框架也會(huì)作一些特殊處理,規(guī)則如下:

CreatedAt:新增數(shù)據(jù)表記錄的時(shí)候,會(huì)自動(dòng)寫入這個(gè)字段。 UpdatedAt:更新數(shù)據(jù)表記錄的時(shí)候,會(huì)自動(dòng)更新這個(gè)字段。 DeletedAt:當(dāng)執(zhí)行軟刪除的時(shí)候,會(huì)自動(dòng)更新這個(gè)字段,表示刪除時(shí)間

gorm.Model

由于如果結(jié)構(gòu)體中有ID,CreatedAt,UpdatedAt,DeletedAt這幾個(gè)比較通用的字段,GORM框架會(huì)自動(dòng)處理這幾個(gè)字段,所以如果我們結(jié)構(gòu)體需要這幾個(gè)字段時(shí),我們可以直接在自定義結(jié)構(gòu)體中嵌入gorm.Model結(jié)構(gòu)體,gorm.Model的結(jié)構(gòu)體如下:

type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}

所以,如果我們?cè)诮Y(jié)構(gòu)體Prize中嵌入gorm.Model,如下:

type Prize struct{
gorm.Model
Name string
}

這樣的話,則結(jié)構(gòu)體Prize包含有五個(gè)字段了。

數(shù)據(jù)庫遷移

我們這里所說的數(shù)據(jù)庫遷移,即通過使用GROM提供的一系列方法,根據(jù)數(shù)據(jù)模型定義好的規(guī)則,進(jìn)行創(chuàng)建、刪除數(shù)據(jù)表等操作,也就是數(shù)據(jù)庫的DDL操作。

GORM提供對(duì)數(shù)據(jù)庫進(jìn)行DDL操作的方法,主要以下幾類:

數(shù)據(jù)表操作

//根據(jù)模型自動(dòng)創(chuàng)建數(shù)據(jù)表
func (s *DB) AutoMigrate(values ...interface{}) *DB 
//根據(jù)模型創(chuàng)建數(shù)據(jù)表
func (s *DB) CreateTable(models ...interface{}) *DB
//刪除數(shù)據(jù)表,相當(dāng)于drop table語句
func (s *DB) DropTable(values ...interface{}) *DB 
//相當(dāng)于drop table if exsist 語句
func (s *DB) DropTableIfExists(values ...interface{}) *DB 
//根據(jù)模型判斷數(shù)據(jù)表是否存在
func (s *DB) HasTable(value interface{}) bool

列操作

//刪除數(shù)據(jù)表字段
func (s *DB) DropColumn(column string) *DB
//修改數(shù)據(jù)表字段的數(shù)據(jù)類型
func (s *DB) ModifyColumn(column string, typ string) *DB

索引操作

//添加外鍵
func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) *DB
//給數(shù)據(jù)表字段添加索引
func (s *DB) AddIndex(indexName string, columns ...string) *DB
//給數(shù)據(jù)表字段添加唯一索引
func (s *DB) AddUniqueIndex(indexName string, columns ...string) *DB

數(shù)據(jù)遷移簡單代碼示例

注意,下面示例程序中db變量代表gorm.DB對(duì)象,其初始化過程本篇不講了。

type User struct {
Id int //對(duì)應(yīng)數(shù)據(jù)表的自增id
Username string
Password string
Email string
Phone string
}
func main(){
db.AutoMigrate(Post{},User{})//創(chuàng)建posts和users數(shù)據(jù)表
db.CreateTable(Post{})//創(chuàng)建posts數(shù)據(jù)表
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(Post{})//創(chuàng)建posts表時(shí)指存在引擎
db.DropTable(Post{},"users")//刪除posts和users表數(shù)據(jù)表
db.DropTableIfExists(Post{},"users")//刪除前會(huì)判斷posts和users表是否存在
//先判斷users表是否存在,再刪除users表
if db.HasTable("users") {
db.DropTable("users")
}
//刪除數(shù)據(jù)表字段
db.Model(Post{}).DropColumn("id")
//修改字段數(shù)據(jù)類型
db.Model(Post{}).ModifyColumn("id","varchar(255)")
//建立posts與users表之間的外鍵關(guān)聯(lián)
db.Model(Post{}).AddForeignKey("uid", "users(id)", "RESTRICT", "RESTRICT")
//給posts表的title字段添加索引
db.Model(Post{}).AddIndex("index_title","title")
//給users表的phone字段添加唯一索引
db.Model(User{}).AddUniqueIndex("index_phone","phone")
}

小結(jié)

可能你會(huì)問,直接在數(shù)據(jù)庫中進(jìn)行數(shù)據(jù)表創(chuàng)建、刪除等操作不就行了嗎?為什么要在應(yīng)用程序里去做這些操作呢?因?yàn)橛行r(shí)候,我們不一定能登錄到數(shù)據(jù)庫系統(tǒng)當(dāng)中,又或者,我們需要開發(fā)一個(gè)可以管理數(shù)據(jù)庫的應(yīng)用程序,這時(shí)候,GROM框架提供的這些數(shù)據(jù)庫遷移的能便派上用場了。

您可能感興趣的文章:
  • gorm update傳入struct對(duì)象,零值字段不更新的解決方案
  • gorm操作MySql數(shù)據(jù)庫的方法
  • Go基于GORM 獲取當(dāng)前請(qǐng)求所執(zhí)行的 SQL 信息(思路詳解)
  • golang Gorm與數(shù)據(jù)庫完整性約束詳解
  • golang gorm 結(jié)構(gòu)體的表字段缺省值設(shè)置方式
  • golang gorm 計(jì)算字段和獲取sum()值的實(shí)現(xiàn)
  • gorm FirstOrCreate和受影響的行數(shù)實(shí)例
  • 解決Go gorm踩過的坑

標(biāo)簽:物業(yè)服務(wù) 安康 青海 海南 遼寧 電子產(chǎn)品 儋州 西雙版納

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Golang 使用gorm添加數(shù)據(jù)庫排他鎖,for update》,本文關(guān)鍵詞  Golang,使用,gorm,添加,數(shù)據(jù)庫,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Golang 使用gorm添加數(shù)據(jù)庫排他鎖,for update》相關(guān)的同類信息!
  • 本頁收集關(guān)于Golang 使用gorm添加數(shù)據(jù)庫排他鎖,for update的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    国产精品123| 日日爽天天| 可以在线看黄的网站| 91麻豆精品国产自产在线| 欧美α片无限看在线观看免费| 四虎影视库| 国产精品123| 国产视频一区二区在线播放| 91麻豆精品国产综合久久久| 久久成人性色生活片| 国产精品自拍在线| 成人免费一级毛片在线播放视频| 午夜在线亚洲| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 久久99欧美| 黄视频网站在线看| 成人免费一级纶理片| 国产91精品一区二区| 国产精品自拍在线观看| 久久99欧美| 日韩中文字幕在线播放| 欧美18性精品| 亚欧成人乱码一区二区| 天天色成人网| 日韩中文字幕在线观看视频| 黄视频网站在线看| 国产一区二区精品| 香蕉视频久久| 国产一区精品| 成人高清视频免费观看| 国产原创视频在线| 天天做日日干| 久久99欧美| 欧美激情一区二区三区在线| 国产91丝袜在线播放0| 精品久久久久久免费影院| 精品久久久久久中文| 精品久久久久久影院免费| 欧美α片无限看在线观看免费| 国产91丝袜在线播放0| 欧美激情一区二区三区视频| 国产精品免费久久| 黄色福利| 亚洲天堂免费| 四虎影视库| 韩国三级视频在线观看| 免费国产在线观看| 香蕉视频亚洲一级| 国产91精品露脸国语对白| 四虎影视久久| 韩国毛片免费大片| 高清一级淫片a级中文字幕| 欧美国产日韩久久久| a级精品九九九大片免费看| 国产亚洲免费观看| 精品国产三级a| 香蕉视频亚洲一级| 免费一级片在线观看| 国产极品白嫩美女在线观看看| 亚洲女初尝黑人巨高清在线观看| 韩国三级视频在线观看| 精品国产亚洲人成在线| 欧美激情伊人| 久久国产精品只做精品| 亚欧乱色一区二区三区| 91麻豆国产福利精品| 韩国毛片| 四虎久久影院| 天天做日日爱| 国产一级生活片| 日本伦理黄色大片在线观看网站| 天天做人人爱夜夜爽2020毛片| 成人av在线播放| 91麻豆精品国产综合久久久| 美国一区二区三区| 国产精品自拍在线观看| 久久成人性色生活片| 国产不卡高清在线观看视频 | 成人在免费观看视频国产| 成人免费观看视频| 免费国产在线观看不卡| 成人高清免费| 黄色福利片| 日韩一级黄色| 国产成人精品综合久久久| 精品国产香蕉在线播出| 欧美激情影院| 青青久久精品| 色综合久久天天综合观看| 香蕉视频久久| 日韩免费在线| 免费国产在线观看| 日本特黄特色aaa大片免费| 一 级 黄 中国色 片| 一级毛片视频免费| 国产精品免费久久| 久久福利影视| 九九久久国产精品| 黄色福利| 国产视频网站在线观看| 国产福利免费视频| 精品国产一区二区三区久久久蜜臀 | 欧美α片无限看在线观看免费| 国产网站免费| 美女被草网站| 日本免费乱人伦在线观看| 午夜在线亚洲| 欧美18性精品| 亚洲精品影院| 999精品视频在线| 九九九国产| 久久99中文字幕久久| 欧美日本免费| 韩国三级一区| 日韩在线观看视频网站| 精品国产亚洲一区二区三区| 精品视频在线观看一区二区| 国产伦精品一区三区视频| 国产精品123| 日韩在线观看网站| 日韩中文字幕在线观看视频| 欧美大片a一级毛片视频| 可以免费看毛片的网站| 日本伦理片网站| 精品视频在线观看一区二区| 精品国产香蕉伊思人在线又爽又黄| 欧美激情一区二区三区视频高清 | 精品久久久久久中文| 亚洲第一页色| 99久久精品国产麻豆| 日韩在线观看免费完整版视频| 精品久久久久久中文字幕2017| 亚洲wwwwww| 国产视频一区在线| 色综合久久天天综合绕观看| 你懂的日韩| 精品在线观看国产| 久久国产一久久高清| 亚洲爆爽| 91麻豆精品国产片在线观看| 韩国三级视频网站| 国产网站免费| 日韩专区第一页| 成人免费观看的视频黄页| 精品久久久久久中文| 国产成人女人在线视频观看| 欧美a级片免费看| 四虎论坛| 黄视频网站免费观看| 国产视频一区在线| 国产伦久视频免费观看 视频| 亚洲wwwwww| 国产a毛片| 天天色色色| 精品国产一区二区三区久久久蜜臀 | 亚洲精品影院一区二区| 成人高清视频在线观看| 免费的黄视频| 91麻豆国产| 午夜在线亚洲男人午在线| 国产综合成人观看在线| 久久精品免视看国产成人2021| 亚洲天堂免费观看| 国产亚洲免费观看| 精品视频在线观看一区二区| 精品国产亚一区二区三区| 91麻豆精品国产自产在线| 成人a级高清视频在线观看| 日韩欧美一二三区| 国产成人女人在线视频观看| 国产精品自拍在线| 午夜久久网| 日本免费乱人伦在线观看| 尤物视频网站在线观看| 黄色免费三级| 国产网站免费视频| 四虎影视库| 国产成人啪精品| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 久久国产一区二区| 欧美激情中文字幕一区二区| 九九久久国产精品| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 亚洲精品影院| 成人免费一级纶理片| 国产不卡在线看| 精品视频在线看 | 韩国毛片免费| 国产一区二区精品久| 成人免费一级毛片在线播放视频| 国产欧美精品| 日日夜夜婷婷| 国产一区二区精品久久91| 亚洲第一色在线| 久久国产精品只做精品| 黄色短视频网站| 国产综合成人观看在线| 国产视频网站在线观看| 青青久久国产成人免费网站| 四虎论坛|