Go 框架三件套 | 青训营笔记

46 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

Go 框架三件套(Web/RPC/ORM)

Gorm

安装

//安装MySQL驱动
go get -u gorm.io/driver/mysql
//安装gorm包
go get -u gorm.io/gorm
//安装gin
go get -u github.com/gin-gonic/gin

连接数据库

var DB *gorm.DB

func init() {
	//配置MySQL连接参数
	username := "root"   //账号
	password := "root" //密码
	host := "127.0.0.1"  //数据库地址,可以是Ip或者域名
	port := 3306         //数据库端口
	Dbname := "gorm"     //数据库名
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, host, port, Dbname)
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	})
	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	DB = db
}

model

type Good struct {
	Id         int  //表字段名为:id
	Name       string //表字段名为:name
	Price      float64 //表字段名为:price
	TypeId     int  //表字段名为:type_id
	CreateTime int64 `gorm:"column:createtime"`  //表字段名为:createtime
}

默认gorm对struct字段名使用Snake Case命名风格转换成mysql表字段名(需要转换成小写字母)

gorm常用标签

标签说明例子
column指定列名gorm:"column:createtime"
primaryKey指定主键gorm:"column:id; PRIMARY_KEY"
-忽略字段gorm:"-" 可以忽略struct字段,被忽略的字段不参与gorm的读写操作

绑定表名

func (u User) TableName() string {
   //绑定MYSQL表名为users
   return "users"
}

增删改查

insert

直接插入

user := User{
	Username:"zhangsan",
	Password:"123456",
	CreateTime:time.Now().Unix(),
}
result := db.Create(&user)
 
result.Error        // 返回 error
result.RowsAffected // 返回插入记录的条数

使用指定字段插入

db.Select("username","password").Create(&user)

update

更新单个字段

DB.Model(&u).Where("id=?",1).Update("username","a")

更新多个字段

DB.Model(&u).Where("id=?",2).Updates(User{
    Username:"b",
    Password:"123",
})

选定某几个字段更新

DB.Model(&u).Where("id=?",3).Select("username").Updates(user) //user自己定义

delete

DB.Delete(&User{},1)

注意删除要带条件,否则会报错

select

  • Take:查询一条记录

    db.Take(&goods)
    
  • First: 查询第一条数据,默认升序

    db.First(&goods)
    
  • Last:查询最后一条记录

    db.Last(&goods)
    
  • Find:查询多条记录

    db.Find(&goods)
    
  • Pluck:查询一列值

    var titles []string
    db.Model(&Goods{}).Pluck("title", &titles)
    

    当 First、Last、Take 方法找不到记录时,GORM 会返回 ErrRecordNotFound 错误

    db.Limit(1).Find(&user)
    

聚合函数

DB.Order("create_time desc").Limit(10).Offset(10).Find(&goods)

ps:order,limit等聚合函数必须写在find的前面

会话与事务

session

为了避免共用db导致的一些问题,gorm提供了会话模式,通过新建session的形式,将db的操作分离,互不影响。

开启会话

db := DB.Session(&gorm.Session{})
// Session 配置
type Session struct {
  DryRun                   bool   //生成 SQL 但不执行
  PrepareStmt              bool   //预编译模式
  NewDB                    bool  //新db 不带之前的条件
  Initialized              bool  //初始化新的db
  SkipHooks                bool  //跳过钩子
  SkipDefaultTransaction   bool  //禁用默认事务
  DisableNestedTransaction bool  //禁用嵌套事务
  AllowGlobalUpdate        bool  //允许不带条件的更新
  FullSaveAssociations     bool  //允许更新关联数据
  QueryFields              bool  //select(字段)
  Context                  context.Context
  Logger                   logger.Interface
  NowFunc                  func() time.Time //允许改变 GORM 获取当前时间的实现
  CreateBatchSize          int  
}
//禁用默认的事务
tx := db.Session(&Session{SkipDefaultTransaction: true})

事务

自动事务

db := DB.Session(&gorm.Session{})
db.Transaction(func(tx *gorm.DB) error {
   // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
   err := tx.Create(&User{Username: "a"}).Error
   if err != nil {
      return err
   }
   err1 := tx.Create(&User{Username: "b"}).Error
   if err1 != nil {
      return err1
   }
   // 返回 nil 提交事务
   return nil
})

手动事务

// 开始事务
tx := db.Begin()

// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)

// ...

// 遇到错误时回滚事务
tx.Rollback()

// 否则,提交事务
tx.Commit()

总结

另外两个rpc和http框架,听了课但又好像只是听了课,这里只分享学习gorm的笔记。