默認狀況下咱們在建立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
複製代碼
歡迎關注公號:程序員的金融圈 一個探討技術,金融,賺錢
的小圈子,爲你提供最有味道
的內容!