GROM|青训营笔记

62 阅读4分钟

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

前言:今天学习ORM框架,ORM是用于与数据库的连接交互的框架。下面简单介绍此框架。

什么时GROM

Object-Relationl Mapping,即对象关系映射,这里的Relationl指的是关系型数据库。

特性

  • 全功能ORM;
  • 关联(包含一个,包含多个,属于,多对多,多种包含);
  • Callbacks(创建/保存/更新/删除/查找之前/之后);
  • 预加载;
  • 事务
  • 复合主键
  • SQL Builder
  • 自动迁移
  • 日志
  • 可扩展,编写基于GORM回调的插件
  • 每个功能都有测试
  • 开发人员友好

安装

使用 go get github.com/jinzhu/gorm 引入

GROM基本使用

// 定义Gorm model
type User struct {
   Code  string
   Prise uint
}

// 为表定义model
func (u User) TableName() string {
   return "user"
}

func main() {
   //连接数据库
   db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3006)/db?charset=utf-8mb4&parseTime=Ture&local=Local"), &gorm.Config{})
   if err != nil {
      fmt.Println("failed to connect database", err)
   }
   //创建数据
   db.Create(&User{Code: "12", Prise: 23})
   var user User
   //查询一条数据
   db.First(&user, 1)
   //更新数据 ,将{code:12,Prise:23} 更改为{code:12,Prise:34}
   db.Model(&user).Update("21", 34)
   //删除数据
   db.Delete(&user, 1)
}

GROM连接的数据库

DSN(数据源)

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
用户名:密码@连接方式(Tcp...)/数据库名称[参数]

MYSQL

dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

SqlServer

dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})

PostgreSQL

dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

SQList

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})

GORM创建

user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} 
result := db.Create(&user) // 通过数据的指针来创建
db.Select("Name", "Age", "CreatedAt").Create(&user)//使用指定字段创建记录

查询

gorm提供了 FirstTakeLast 方法,方便从数据库中检索。

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

// 获取一条记录,没有指定排序字段  
db.Take(&user)  // SELECT * FROM users LIMIT 1;  
  
// 获取最后一条记录(主键降序)  
db.Last(&user) // SELECT * FROM users ORDER BY id DESC LIMIT 1;  

//查询全部对象
result := db.Find(&users) //SELECT * FROM users;

//按条件查询
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;

// Struct
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;

// Map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;

参考:GRom文档

更新

当使用 Update 更新单列时,需要有一些条件,否则将会引起错误 ErrMissingWhereClause

// 条件更新 
db.Model(&User{}).Where("active = ?", true).Update("name", "hello") 
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true; 

// User 的 ID 是 `111` 
db.Model(&user).Update("name", "hello") 
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; 

// 根据条件和 model 的值进行更新 
db.Model(&user).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true; 

// 根据 `struct` 更新属性,只会更新非零值的字段  
db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})  
// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;  
  
// 根据 `map` 更新属性  
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})  
// UPDATE users SET name='hello', age=18, active=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

//选择更新字段
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "active": false})
// UPDATE users SET name='hello' WHERE id=111;

删除

物理删除

直接删除记录

db.Delete(&User{},1) //DELETE FROM users WHERE id = 1;
db.Delete(&User{},"1") //DELETE FROM users WHERE id = 1;
db.Delete(&User{},[]int{1,2,3}) //DELETE FROM users WHERE id (1,2,3);
db.Where("name like ?","%jin%").Delete(User{}) //DELETE FROM users WHERE name like "%jin%";
db.Delete(User{},"email like ?", "%jin%") //DELETE FROM users WHERE name like "%jin%";

软删除

如果模型包含了一个 gorm.deletedat 字段(gorm.Model 已经包含了该字段),它将自动获得软删除的能力。拥有软删除能力的模型调用 Delete 时,记录不会从数据库中被真正删除。但 GORM 会将 DeletedAt 置为当前时间, 并且你不能再通过普通的查询方法找到该记录。

// user 的 ID 是 `111`  
db.Delete(&user)  
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;  
  
// 批量删除  
db.Where("age = ?", 20).Delete(&User{})  
// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;  
  
// 在查询时会忽略被软删除的记录  
db.Where("age = 20").Find(&user)  
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;

事务

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

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

// ...

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

// 否则,提交事务
tx.Commit()
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{   
SkipDefaultTransaction: true, //关闭默事务
PrepareStmt:true, // 预存预编译语句

})