gorm使用總結


時間也會有差錯,也會出故障,它也能被撕成碎片,在一間屋子里留下一塊永恆的碎屑。
——馬爾克斯
目錄

gorm操作的db實例

初始化表

普通查詢

使用原生SQL

創建操作

修改操作

刪除操作

校驗是否存在

操作時忽略某屬性

gorm結構體Tag

自定義列名稱

使用過程中的一些坑

gorm操作的db實例
var db *gorm.DB
初始化表
//待創建的表對應的結構體
var tables = []interface{}{
&model.Customer{},
&model.Order{},
&model.OrderItem{},
}

var gdb *gorm.DB

func Connection() *gorm.DB {
return gdb
}
var conn = config.Connection()

func InitTable() {
err := CheckTable()
if err != nil {
log.Fatal("check table err: ", err.Error())
}
log.Println("check table completed!")
}

func CheckTable() error {
var err error
for _, table := range tables {
flag := conn.HasTable(table)
if !flag {
err = conn.CreateTable(table).Error
if err != nil {
log.Fatal("create table err: ", err.Error())
break
}
log.Printf("create table %v success.", table)
continue
}
}
return err
}
普通查詢
func GetGroupByIDInternal(id string) (group model.MsGroup, err error) (error){
db := config.Connection()
return db.Where("id = ?", id).Find(&group).Error
}
說明:

1,model.MsGroup 是與數據庫表對應的結構體,以上代碼查詢的就是ms_group表中的數據,

2,條件是以id查詢,

3,一般在查詢的最后使用.Error()來返回錯誤,查到的所有數據會存到Find方法的參數group這個對象中。

4,有幾個參數就有幾個?

使用原生SQL
//查詢
func ListCatalogAppByProjectIdInternal(projectID string) (gc []model.MsGroupCatalogApp, err error) {
err = config.Connection().Raw("SELECT * FROM ms_group_catalog_app WHERE deleted_at IS NULL " +
"AND parent_group_id IN (SELECT id FROM ms_group WHERE deleted_at IS NULL AND project_id = ?);", projectID).Find(&gc).Error
return gc, err
}

//其他增刪改操作
db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})
說明:

1,以上代碼查詢的是ms_group_catalog_app這個表中的數據,且按自定義需求使用自己寫的SQL,

2,除過使用db.Raw("SQL語句").Find(&對象) 能執行查詢SQL,也可使用

db.Raw("sql語句",變量).Scan(&存放的結構體對象)
來執行查詢。

創建操作
func CreateGroupCatalogAppInternal(data model.MsGroupCatalogApp) error {
return config.Connection().Create(&data).Error
}
說明:data是你要創建ms_group_catalog_app這個表的待插入記錄

修改操作
//修改所傳的
func updateReceiver(receiver *model.Receiver)error{
return config.Connection().Model(receiver).Where("id = ?",receiver.Id).Update(receiver).Error
}

//只修改表中某1列值,如只修改allow_create的值
func UpdateClusterConfigInternal(conf model.ClusterConfig, tx *gorm.DB) error {
if tx != nil {
return tx.Model(&conf).Where("cluster_id = ?", conf.ClusterID).Update("allow_create", conf.AllowCreate).Error
}
return config.Connection().Model(&conf).Where("cluster_id = ?", conf.ClusterID).Update("allow_create", conf.AllowCreate).Error
}
//UPDATE cluster_config SET allow_create=conf.AllowCreate, updated_at='2019-7-26 15:34:10' WHERE cluster_id = conf.ID

//修改多個值
func UpdateNormsInternal(norm model.ContainerNorms, tx *gorm.DB) error {
if tx != nil {
return tx.Model(&norm).Where("id = ?", norm.ID).
Omit("is_default", "created_at").
Updates(map[string]interface{}{"cpu": norm.Cpu, "memory": norm.Memory}).Error
}
return config.Connection().Model(&norm).Where("id = ?", norm.ID).
Omit("is_default", "created_at").
Updates(map[string]interface{}{"cpu": norm.Cpu, "memory": norm.Memory}).Error
}
//UPDATE container_norms SET memory= norm.Memory,cpu= norm.Cpu, updated_at='2019-7-26 15:34:10' WHERE id = norm.ID
說明:使用Save()方法也能達到目的,但Save()操作的是所有列,慎用。

刪除操作
func delReceiver(id string)error{
return config.Connection().Where("id = ?",id).Delete(&model.Receiver{}).Error
}
校驗是否存在
func CheckReceiverExistByName(Name string)bool{
return config.Connection().Where("name = ?",Name).Find(&model.Receiver{}).RecordNotFound()
}
在查詢最后使用.RecordNotFound()可直接得知該條記錄是否存在,返回true則表示沒有這條記錄,返回false則表明該條數據已存在。

操作時忽略某屬性
func UpdateGroupInternal(group model.MsGroup, tx *gorm.DB) error {
return config.Connection().Model(&group).Where("id = ?", group.ID).Omit("name", "created_at", "project_id").Save(&group).Error
}
使用Omit方法,以上代碼是修改操作,修改時將不會修改name,created_at, project_id這三項屬性。

gorm結構體Tag
type Model struct {
ID string `gorm:"primary_key"`
CreatedAt int64
UpdatedAt *time.Time `json:"UpdatedAt,omitempty"`
DeletedAt *time.Time `sql:"index" json:"-"`
}

type MsGroup struct {
Model
Name string `json:"name" gorm:"not null"`
ProjectID string `json:"projectId" gorm:"not null"`
Description string `json:"description"`
Workloads []Workload `json:"workloads" gorm:"-"`
CatalogApps []CatalogApp `json:"catalogApps" gorm:"-"`
}
使用``來寫tag,gorm的tag以gorm開頭,如果屬性是主鍵,標注gorm:"primary_key" ;如果使用了gorm:"-"則表示有關於gorm的操作時忽略這個字段,比如建表時。

常用Tag如下表:


tag名稱 含義
gorm:"primary_key" 主鍵
gorm:"not null" 該屬性不能為空
gorm:"AUTO_INCREMENT" 該屬性自增
gorm:"size:255" 對應的表中長度大小
gorm:"-" 忽略該屬性
gorm:"not null;unique"
設置字段非空且唯一

gorm:"type:text" 表的該列類型為text

 

 

 

 

 

 

 

自定義列名稱
默認情況下(不加指定tag時),建表后的列名如下:

type User struct {
ID uint // 列名為 `id`
Name string // 列名為 `name`
Birthday time.Time // 列名為 `birthday`
CreatedAt time.Time // 列名為 `created_at`
}
如果需要自定義列名:

type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // 設置列名為`beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // 設置列名為`day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // 設置列名為`age_of_the_beast`
}
即,使用`gorm:"column:name"`

使用過程中的一些坑
1,.Count()函數在特定情況下返回的記錄數量不是正確的值

解決辦法:調整語句,查詢多次,分別查詢

2,deleted_at是Model結課體的既定字段,刪除記錄時表的該條記錄不會實際刪除,而是deleted_at置為非空(刪除操作時的時間),此時如果你的表結構設計的有些紕漏,那么功能就會有bug,如ID字段使用未來可能繼續出現的值時。

解決辦法:重新調整列功能及值,增加列

3,當對含有布爾值的結構體進行修改操作時,且修改到了這一列,那么此時使用.Update(&結構體變量)是不生效的,不生效體現為修改為true時能正常修改,修改為false時數據庫中值不變。那么這種情況怎么解決?看上面列舉的修改操作的幾種情況就可以了。


————————————————
版權聲明:本文為CSDN博主「_雨落山嵐」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/HYZX_9987/article/details/99681632


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM