这是我参与「第五届青训营」伴学笔记创作活动的第6天
前言
Go框架三件套第一部分。
Gorm
概述
Gorm是Golang语言中一款性能极好的ORM库,对开发人员相对是比较友好的。(ORM:Object-Relationl Mapping,即对象关系映射。)
上手
# 使用docker快速创建一个本地可连接的mysql实例
$ docker run -itd -e MYSQL_ROOT_PASSWORD='bgbiao.top' --name go-orm-mysql -p 13306:3306 mysql:5.6
# 登陆mysql并创建一个测试库
$ docker exec -it go-orm-mysql mysql -uroot -pbgbiao.top
....
mysql> create database test_api;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test_api |
+--------------------+
4 rows in set (0.00 sec)
# 运行一个简单示例
$ cat gorm-mysql-example.go
package main
import (
"fmt"
"time"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// 定义一个数据模型(user表)
// 列名是字段名的蛇形小写(PassWd->pass_word)
type User struct {
Id uint `gorm:"AUTO_INCREMENT"`
Name string `gorm:"size:50"`
Age int `gorm:"size:3"`
Birthday *time.Time
Email string `gorm:"type:varchar(50);unique_index"`
PassWord string `gorm:"type:varchar(25)"`
}
var db *gorm.DB
func main() {
db,err := gorm.Open("mysql","root:bgbiao.top@(127.0.0.1:13306)/test_api?charset=utf8&parseTime=True&loc=Local")
if err != nil {
fmt.Errorf("创建数据库连接失败:%v",err)
}
defer db.Close()
// 自动迁移数据结构(table schema)
// 注意:在gorm中,默认的表名都是结构体名称的复数形式,比如User结构体默认创建的表为users
// db.SingularTable(true) 可以取消表名的复数形式,使得表名和结构体名称一致
db.AutoMigrate(&User{})
// 添加唯一索引
db.Model(&User{}).AddUniqueIndex("name_email", "id", "name","email")
// 插入记录
db.Create(&User{Name:"bgbiao",Age:18,Email:"bgbiao@bgbiao.top"})
db.Create(&User{Name:"xxb",Age:18,Email:"xxb@bgbiao.top"})
var user User
var users []User
// 查看插入后的全部元素
fmt.Printf("插入后元素:\n")
db.Find(&users)
fmt.Println(users)
// 查询一条记录
db.First(&user,"name = ?","bgbiao")
fmt.Println("查看查询记录:",user)
// 更新记录(基于查出来的数据进行更新)
db.Model(&user).Update("name","biaoge")
fmt.Println("更新后的记录:",user)
// 删除记录
db.Delete(&user)
// 查看全部记录
fmt.Println("查看全部记录:")
db.Find(&users)
fmt.Println(users)
}
# 运行gorm实例
$ go run gorm-mysql-example.go
插入后元素:
[{1 bgbiao 18 <nil> bgbiao@bgbiao.top } {2 xxb 18 <nil> xxb@bgbiao.top }]
查看查询记录: {1 bgbiao 18 <nil> bgbiao@bgbiao.top }
更新后的记录: {1 biaoge 18 <nil> bgbiao@bgbiao.top }
查看全部记录:
[{2 xxb 18 <nil> xxb@bgbiao.top }]
GORM的基本使用
增、删、改表结构
// 使用模型创建
db.CreateTable(&User{})
// 增加参数创建
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
// 删除表
db.DropTable(&User{})
db.DropTable("users")
// 模型和表名的混搭
db.DropTableIfExists(&User{}, "products")
// 修改列(修改字段类型)
db.Model(&User{}).ModifyColumn("description", "text")
// 删除列
db.Model(&User{}).DropColumn("description")
// 指定表名创建表
db.Table("deleted_users").CreateTable(&User{})
// 指定表名查询
var deleted_users []User
db.Table("deleted_users").Find(&deleted_users)
创建
插入记录
// 相当于insert into users(name,age,brithday) values("BGBiao",18,time.Now())
user := User{Name: "BGBiao", Age: 18, Birthday: time.Now()}
// 主键为空返回`true`
db.NewRecord(user)
db.Create(&user)
// 创建`user`后返回`false`
db.NewRecord(user)
查询
基本查询
// 根据主键查询第一条记录
// SELECT * FROM users ORDER BY id LIMIT 1;
db.First(&user)
// 随机获取一条记录
// SELECT * FROM users LIMIT 1;
db.Take(&user)
// 根据主键查询最后一条记录
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
db.Last(&user)
// 查询所有的记录
// SELECT * FROM users;
db.Find(&users)
// 查询指定的某条记录(仅当主键为整型时可用)
// SELECT * FROM users WHERE id = 10;
db.First(&user, 10)
结构体方式查询
// 结构体方式
// select * from users where name = 'bgbiao.top'
db.Where(&User{Name: "bgbiao.top", Age: 20}).First(&user)
// Map方式
// select * from users where name = 'bgbiao.top' and age = 20;
db.Where(map[string]interface{}{"name": "bgbiao.top", "age": 20}).Find(&users)
// 主键的切片
// select * from users where id in (20,21,22);
db.Where([]int64{20, 21, 22}).Find(&users)
更新
更新所有字段
注意:save会更新所有字段,及时没有赋值
db.First(&user)
user.Name = "bgbiao.top"
user.Age = 100
// update users set name = 'bgbiao.top',age=100 where id = user.id
db.Save(&user)
更新修改字段
使用Update和Updates方法
// 更新单个属性,如果它有变化
// update users set name = 'hello' where id = user.id
db.Model(&user).Update("name", "hello")
// 根据给定的条件更新单个属性
// update users set name = 'hello' where active = true
db.Model(&user).Where("active = ?", true).Update("name", "hello")
// 使用 map 更新多个属性,只会更新其中有变化的属性
// update users set name = 'hello',age=18,actived=false where id = user.id
db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
// 使用 struct 更新多个属性,只会更新其中有变化且为非零值的字段
db.Model(&user).Updates(User{Name: "hello", Age: 18})
// 警告:当使用 struct 更新时,GORM只会更新那些非零值的字段
// 对于下面的操作,不会发生任何更新,"", 0, false 都是其类型的零值
db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
更新选定字段
如果想要更新或者忽略某些字段,可以先使用Select或Omit
// update users set name = 'hello' where id = user.id;
db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
// Omit()方法用来忽略字段
// update users set age=18,actived=false where id = user.id
db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
SQL表达式更新
// update products set price = price*2+100 where id = product.id
DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
// update products set price = price*2+100 where id = product.id;
DB.Model(&product).Updates(map[string]interface{}{"price": gorm.Expr("price * ? + ?", 2, 100)})
// update products set quantity = quantity-1 where id = product.id;
DB.Model(&product).UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
// update products set quantity = quantity -1 where id = product.id and quantity > 1
DB.Model(&product).Where("quantity > 1").UpdateColumn("quantity", gorm.Expr("quantity - ?", 1))
删除
删除记录
注意: 删除记录时,请确保主键字段有值,GORM 会通过主键去删除记录,如果主键为空,GORM 会删除该 model 的所有记录。
// 删除现有记录
// delete from emails where id = email.id;
db.Delete(&email)
// 为删除 SQL 添加额外的 SQL 操作
// delete from emails where id = email.id OPTION (OPTIMIZE FOR UNKNOWN)
db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
待整理后持续更新