GoFrame 鏈?zhǔn)讲僮?寫入保存

2022-04-01 16:55 更新

Insert/Replace/Save

這幾個(gè)鏈?zhǔn)讲僮鞣椒ㄓ糜跀?shù)據(jù)的寫入,并且支持自動(dòng)的單條或者批量的數(shù)據(jù)寫入,區(qū)別如下:

  • ?Insert?:使用?INSERT INTO?語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),返回失敗,否則寫入一條新數(shù)據(jù);
  • ?Replace?:使用?REPLACE INTO?語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),會(huì)刪除原有的記錄,必定會(huì)寫入一條新記錄;
  • ?Save?:使用?INSERT INTO?語句進(jìn)行數(shù)據(jù)庫寫入,如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),更新原有數(shù)據(jù),否則寫入一條新數(shù)據(jù);

在部分?jǐn)?shù)據(jù)庫類型中,并不支持?Replace/Save?方法。

這幾個(gè)方法往往需要結(jié)合?Data?方法使用,該方法用于傳遞數(shù)據(jù)參數(shù),用于數(shù)據(jù)寫入/更新等寫操作,支持的參數(shù)為?string/map/slice/struct/*struct?。例如,在進(jìn)行?Insert?操作時(shí),開發(fā)者可以傳遞任意的?map?類型,如: ?map[string]string/map[string]interface{}/map[interface{}]interface{}?等等,也可以傳遞任意的?struct/*struct/[]struct/[]*struct?類型。此外,這幾個(gè)方法的參數(shù)列表也支持直接的?data?參數(shù)輸入,該參數(shù)?Data?方法參數(shù)一致。

InsertIgnore

從?goframe v1.9.0?版本開始,?goframe?的?ORM?提供了一個(gè)常用寫入方法?InsertIgnore?,用于寫入數(shù)據(jù)時(shí)如果寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí),忽略錯(cuò)誤繼續(xù)執(zhí)行寫入。該方法定義如下:

func (m *Model) InsertIgnore(data ...interface{}) (result sql.Result, err error)

InsertAndGetId

從?goframe v1.15.7?版本開始,?goframe?的?ORM?同時(shí)也提供了一個(gè)常用寫入方法?InsertAndGetId?,用于寫入數(shù)據(jù)時(shí)并直接返回自增字段的ID。該方法定義如下:

func (m *Model) InsertAndGetId(data ...interface{}) (lastInsertId int64, err error)

OnDuplicate/OnDuplicateEx

?OnDuplicate/OnDuplicateEx?方法需要結(jié)合?Save?方法一起使用,用于指定?Save?方法的更新/不更新字段,參數(shù)為字符串、字符串?dāng)?shù)組、?Map?。例如:

OnDuplicate("nickname, age")
OnDuplicate("nickname", "age")
OnDuplicate(g.Map{
    "nickname": gdb.Raw("CONCAT('name_', VALUES(`nickname`))"),
})
OnDuplicate(g.Map{
    "nickname": "passport",
})

其中?OnDuplicateEx?用于排除指定忽略更新的字段,排除的字段需要在寫入的數(shù)據(jù)集合中。

使用示例

示例1,基本使用

數(shù)據(jù)寫入/保存方法往往需要結(jié)合?Data?方法使用:

// INSERT INTO `user`(`name`) VALUES('john')
g.Model("user").Data(g.Map{"name": "john"}).Insert()

// INSERT IGNORE INTO `user`(`uid`,`name`) VALUES(10000,'john')
g.Model("user").Data(g.Map{"uid": 10000, "name": "john"}).InsertIgnore()

// REPLACE INTO `user`(`uid`,`name`) VALUES(10000,'john')
g.Model("user").Data(g.Map{"uid": 10000, "name": "john"}).Replace()

// INSERT INTO `user`(`uid`,`name`) VALUES(10001,'john') ON DUPLICATE KEY UPDATE `uid`=VALUES(`uid`),`name`=VALUES(`name`)
g.Model("user").Data(g.Map{"uid": 10001, "name": "john"}).Save()

也可以不使用?Data?方法,而給寫入/保存方法直接傳遞數(shù)據(jù)參數(shù):

g.Model("user").Insert(g.Map{"name": "john"})
g.Model("user").Replace(g.Map{"uid": 10000, "name": "john"})
g.Model("user").Save(g.Map{"uid": 10001, "name": "john"})

數(shù)據(jù)參數(shù)也常用struct類型,例如當(dāng)表字段為 ?uid/name/site? 時(shí):

type User struct {
    Uid  int    `orm:"uid"`
    Name string `orm:"name"`
    Site string `orm:"site"`
}
user := &User{
    Uid:  1,
    Name: "john",
    Site: "https://goframe.org",
}
// INSERT INTO `user`(`uid`,`name`,`site`) VALUES(1,'john','https://goframe.org')
g.Model("user").Data(user).Insert()

示例2,數(shù)據(jù)批量寫入

// INSERT INTO `user`(`name`) VALUES('john_1'),('john_2'),('john_3')
g.Model("user").Data(g.List{
    {"name": "john_1"},
    {"name": "john_2"},
    {"name": "john_3"},
}).Insert()

可以通過?Batch?方法指定批量操作中分批寫入條數(shù)數(shù)量(默認(rèn)是10),以下示例將會(huì)被拆分為兩條寫入請(qǐng)求:

// INSERT INTO `user`(`name`) VALUES('john_1'),('john_2')
// INSERT INTO `user`(`name`) VALUES('john_3')
g.Model("user").Data(g.List{
    {"name": "john_1"},
    {"name": "john_2"},
    {"name": "john_3"},
}).Batch(2).Insert()

示例3,數(shù)據(jù)批量保存

批量保存操作與單條保存操作原理是一樣的,當(dāng)寫入的數(shù)據(jù)中存在主鍵或者唯一索引時(shí)將會(huì)更新原有記錄值,否則新寫入一條記錄。

// INSERT INTO `user`(`uid`,`name`) VALUES(10000,'john_1'),(10001,'john_2'),(10002,'john_3')
// ON DUPLICATE KEY UPDATE `uid`=VALUES(`uid`),`name`=VALUES(`name`)
g.Model("user").Data(g.List{
    {"uid":10000, "name": "john_1"},
    {"uid":10001, "name": "john_2"},
    {"uid":10002, "name": "john_3"},
}).Save()

RawSQL語句嵌入

?gdb.Raw?是字符串類型,該類型的參數(shù)將會(huì)直接作為?SQL?片段嵌入到提交到底層的?SQL?語句中,不會(huì)被自動(dòng)轉(zhuǎn)換為字符串參數(shù)類型、也不會(huì)被當(dāng)做預(yù)處理參數(shù)。例如:

// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES('id+2','john','123456','now()')
g.Model("user").Data(g.Map{
	"id":          "id+2",
	"passport":    "john",
	"password":    "123456",
	"nickname":    "JohnGuo",
	"create_time": "now()",
}).Insert()
// 執(zhí)行報(bào)錯(cuò):Error Code: 1136. Column count doesn't match value count at row 1

使用?gdb.Raw?改造后:

// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES(id+2,'john','123456',now())
g.Model("user").Data(g.Map{
	"id":          gdb.Raw("id+2"),
	"passport":    "john",
	"password":    "123456",
	"nickname":    "JohnGuo",
	"create_time": gdb.Raw("now()"),
}).Insert()


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)