Golang 链接数据库 Gorm 使用笔记

中文文档地址:https://jasperxu.github.io/gorm-zh/mysql

英文Doc: https://gorm.io/docs/git

(逐步更新)github

1. 基本操做golang

  1)链接数据库sql

          链接后能够设置最大链接数等参数    数据库

db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")

  2) 读取数据api

    读取数据须要定义struct,经过映射Struct参数与table列的名称,为struct对象赋值,列名是Struct参数名的蛇形小写+下划线。也能够加备注`gorm:"column:<new column name>"`  ,重设匹配的列名,具体使用例子见下方。数组

    a) 指定表名称:配置struct链接table名称,为struct配置TableName()方法:app

<definition of your struct>

func (<struct name>) TableName() string { return "<table name>" }
db.Model(&<add struct name here>{})

  b) 指定列名称:(来自手册): ui

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`
}

  c) 如何获取查询到的数据?

  用api,user能够是struct的slice或者单一对象:

// 获取第一条记录,按主键排序
db.First(&user) //// SELECT * FROM users ORDER BY id LIMIT 1;

// 获取最后一条记录,按主键排序
db.Last(&user) //// SELECT * FROM users ORDER BY id DESC LIMIT 1;

// 获取全部记录
db.Find(&users) //// SELECT * FROM users;

// 使用主键获取记录 / 这个能够直接用where作。。
db.First(&user, 10) //// SELECT * FROM users WHERE id = 10;

  也能够选择用Scan将结果扫描到结构体中(变量名要匹配)

type Result struct { Name string Age int } var result Result db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)

  sql返回多条数据时,能够将结果扫描进数组,另外一种方式是使用.Rows(),逐行读取数据。

  3)Update

    只要执行就update,更新user

db.Save(&user)

     也有update方法,若是有筛选条件(where),夹在update前。

db.Model(&user).Update("name", "hello")

     其余update方法能够check官方文档

     4) 读锁

  Select for Update

db.First(&model).ForUpdate()

 

拓展用法:

  1. Batch Insert

  参考:https://github.com/jinzhu/gorm/issues/255#issuecomment-481159929

type OwnDb struct { *gorm.DB } func (db *OwnDb)BatchInsert(objArr []interface{}) (int64, error) { // If there is no data, nothing to do.
    if len(objArr) == 0 { return 0, errors.New("insert a slice length of 0") } mainObj := objArr[0] mainScope := db.NewScope(mainObj) mainFields := mainScope.Fields() quoted := make([]string, 0, len(mainFields)) for i := range mainFields { // If primary key has blank value (0 for int, "" for string, nil for interface ...), skip it. // If field is ignore field, skip it.
        if (mainFields[i].IsPrimaryKey && mainFields[i].IsBlank) || (mainFields[i].IsIgnored) { continue } quoted = append(quoted, mainScope.Quote(mainFields[i].DBName)) } placeholdersArr := make([]string, 0, len(objArr)) for _, obj := range objArr { scope := db.NewScope(obj) fields := scope.Fields() placeholders := make([]string, 0, len(fields)) for i := range fields { if (fields[i].IsPrimaryKey && fields[i].IsBlank) || (fields[i].IsIgnored) { continue } var vars  interface{} if (fields[i].Name == "CreatedAt" || fields[i].Name == "UpdatedAt") && fields[i].IsBlank { vars = gorm.NowFunc() } else { vars = fields[i].Field.Interface() } placeholders = append(placeholders, scope.AddToVars(vars)) } placeholdersStr := "(" + strings.Join(placeholders, ", ") + ")" placeholdersArr = append(placeholdersArr, placeholdersStr) // add real variables for the replacement of placeholders' '?' letter later.
        mainScope.SQLVars = append(mainScope.SQLVars, scope.SQLVars...) } mainScope.Raw(fmt.Sprintf("INSERT INTO %s (%s) VALUES %s", mainScope.QuotedTableName(), strings.Join(quoted, ", "), strings.Join(placeholdersArr, ", "), )) //Execute and Log
    if err :=mainScope.Exec().DB().Error;err != nil { return 0,err } return mainScope.DB().RowsAffected,nil }

 

如何用?

db,err := gorm.Open(c.Driver, uri) if err != nil { panic("Database connection failed") } db.LogMode(c.LogMode) DB := &OwnDb{DB:db}
yourDataList := make([]interface{}, len(...)) 向这里append batchInsert(db, yourDataList)

 

  2. Transaction

  一个思路:把rollback写入defer recover / err中,一旦发生panic就回滚rollback,执行所有命令就commit

// begin a transaction
tx := db.Begin() // do some database operations in the transaction (use 'tx' from this point, not 'db')
tx.Create(...) // ... // rollback the transaction in case of error
tx.Rollback() // Or commit the transaction
tx.Commit()

 

func Transaction(){ conn, tx := NewTransaction(db.Begin()) defer tx.Close() if err := conn.Create(&xxx).Error; err != nil { tx.Fail() } if err := conn.Update(&yyy); err != nil { tx.Fail() } if err := conn.tx.Delete(&zzz); err != nil { tx.Fail() }  //add other err you want to handle here }) }
相关文章
相关标签/搜索