Go語言工具箱--Gorm獲取新增記錄自增主鍵,使用NewScope仍是降級處理?

默認狀況下咱們在建立mysql表結構的時候會設置一個自增的主鍵id,建立好一條記錄以後,使用該主鍵id關聯其餘的業務。mysql

表結構以下:程序員

CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
複製代碼

Gorm默認提供的Create方法在建立一條數據以後,能夠以前的對象中獲取,如:sql

type Tests struct {
	Id   int64  `json:"id"`
	Name string `json:"name"`
	Age  int64  `json:"age"`
}

mbr := Tests{
	Name: "111",
	Age:  10,
}
err = db.Table("test").Create(&mbr).Error
複製代碼

建立以後,可以經過mbr.Id獲取自增編號。數據庫

可是,使用這種方式有個尷尬的地方,萬一Age或者Name字段爲空怎麼辦呢?json

以下代碼:bash

type Tests struct {
	Id   int64  `json:"id"`
	Name string `json:"name"`
	Age  int64  `json:"age"`
}

mbr := Tests{
	Name: "111",
}
err = db.Table("test").Create(&mbr).Error
複製代碼

執行的sql語句以下,會給age設置一個默認值0,可是數據庫默認值爲NULL,0能夠是具備業務意義的。ui

INSERT  INTO `test` (`name`,`age`) VALUES ('111',0)
複製代碼

那麼如何才能避免沒有0的狀況發生呢?spa

有以下三種方法,都是經過model結構提對象的改動實現。指針

  • 方法一,給結構體增長default字段,sSql語句在拼裝的時候就不會設置空值,可是默認值也不會生效,顯得累贅。
type Tests struct {
	Id   int64  `json:"id"`
	Name string `json:"name"`
	Age  int64  `gorm:"default:'0'"json:"age"`
}

mbr := Tests{
	Name: "222",
}
err = db.Table("test").Create(&mbr).Error
複製代碼

執行的sql語句:code

INSERT  INTO `test` (`name`) VALUES ('222')
複製代碼
  • 方法二,修改結構體變量的類型爲指針類型
type Tests struct {
	Id   int64  `json:"id"`
	Name string `json:"name"`
	Age  *int64 `json:"age"`
}

mbr := Tests{
	Name: "111",
}
err = db.Table("test").Create(&mbr).Error
複製代碼

執行的sql語句以下,將空指針轉化爲NULL

INSERT  INTO `test` (`name`,`age`) VALUES ('111',NULL)
複製代碼
  • 方法三,使用sql.NullInt64定義字段
type Tests struct {
	Id   int64  `json:"id"`
	Name string `json:"name"`
	Age  sql.NullInt64
}

mbr := Tests{
	Name: "111",
}
err = db.Table("test").Create(&mbr).Error
複製代碼

執行的sql語句和方法二相同。

INSERT  INTO `test` (`name`,`age`) VALUES ('111',NULL)
複製代碼

以上三種方法都在必定程度上增長結構體對象的複雜程度,但理想的方式是保持結構體對象的簡單直觀。

因而,能夠採起直接寫sql方法,雖然可以實現新增的方法,可是沒法獲取到插入那一行數據的自增id。

dbRes := db.Table("test").Exec("insert into test (name) values('pengj')")
fmt.Println("value ->",dbRes.Value)
複製代碼

看了gorm源碼實現以後發現,不管是Create仍是Update方法在調用的時候都調用了NewScope方法,因而嘗試使用下面的方式:

mbr := Tests{}
db.Table("test").NewScope(mbr).Raw("insert into test (name) values('xm')").Exec()
fmt.Println( mbr)
複製代碼

開始覺得,數據建立以後的完整數據都會放到mbr中,可是大失所望,mbr對象中仍是沒有自增主鍵id

繼續看代碼,gorm這個orm既然是對底層database/sql的封裝,那麼若是降級處理,是否是能夠解決問題呢?

繼續開代碼以後,發現了下面的實現方式:

res, err := db.CommonDB().Exec("insert into test (name) values('xm')")
if err != nil {
	panic(err)
}
affectId, _ := res.RowsAffected()
insertId, _ := res.LastInsertId()
fmt.Println("affectId && insertId ", affectId, insertId)
複製代碼

最終輸出以下結果,解決文章開始提出的問題,insertId也就是表結構中的自增id的值。

affectId && insertId  1 110
複製代碼

歡迎關注公號:程序員的金融圈 一個探討技術,金融,賺錢的小圈子,爲你提供最有味道的內容!

相關文章
相關標籤/搜索