这是我参与【第五届青训营】伴学笔记创作活动的第五天
Go框架三件套-Gorm
1. 框架介绍
- Gorm
Gorm是一个已经迭代了10年+的ORM框架(对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM框架是连接数据库的桥梁,只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。)。
- Kitex
字节跳动内部的Golang微服务RPC框架,具有高性能,强扩展的主要特点,支持多协议并且用于丰富的开源扩展。
- Hertz
字节跳动内部的HTTP框架,参考了其他开源框架的优势。
2.三件套的使用
Gorm
以CRUD(增删改查)来看,该框架的使用方法如下:
- 安装依赖包:操作Mysql需要安装两个包
- MySQL驱动包
- GORM包 使用go get命令安装依赖包
- 导入依赖包
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
- Gorm操作Mysql例子
package main
//安装MySQL驱动
//go get -u gorm.io/driver/mysql
//安装gorm包
//go get -u gorm.io/gorm
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type tb_user struct{
//Gorm使用名为ID的字段作为主键
Id uint `gorm:"primarykey"`
//结构的变量名称需要为表中列名的首字母大写,若有`gorm:"column:username"`,则结构体的变量名称可以随意定义
Username string `gorm:"column:username"` //`gorm:"default:xxxx"`设置默认值
Address string `gorm:"column:address"`
}
func(p tb_user) TableName() string{
return "tb_user"
}
func main(){
db,err:=gorm.Open(
mysql.Open("root:Hjl+20000401@tcp(127.0.0.1:3306)/cloud_user?charset=utf8mb4&parseTime=True&loc=Local"),
&gorm.Config{})
//连接数据库
if err!=nil {
panic("failed to connect database")
}
//创建单条数据
db.Create(&tb_user{Username:"叶黄素",Address: "要买一瓶"})
//创建多条数据
users:=[]*tb_user{{Username: "bbb",Address: "lll"},{Username: "ccc",Address: "lll"},{Username: "ddd",Address: "lll"}}
db.Create(users)
//读取数据
var user tb_user
db.First(&user,1)
//更新数据
db.Model(&user).Update("username","Cool")
//更新多个字段
db.Model(&user).Updates(tb_user{Username: "aaa",Address: "bbb"})
//删除数据,但是只能删除该查找到的数据,而且第二个属性必须是该数据的主键值
db.Delete(&user,1)
}
- 查询数据
//获取第一条记录(主键升序),查询不到数据则返回ErrRecordNotFound
u:=&User{}
db.First(u)
//查询多条数据
users:=make([]*User,0)
//SELECT * FROM where age>10;
result:=db.where("age>10").Find(&users)
//返回找到的记录数,相当于len(users)
fmt.Println(result.RowAffected)
//IN SELECT * FROM users WHERE name IN ("jinzhu","jinzhu 2")
db.where("name IN",[]string{"jinzhu","jinzhu 2"}).Find(&users)
//LIKE SELECT * FROM users WHERE name LIKE '%jin%'
db.where("name like ?","%jin%").Find(&users)
//AND SELECT * FROM users WHERE name = 'jinzhu' AND age >=22
db.where("name = ? AND age >= ?","jinzhu","22").Find(&users)
/*
当使用结构体作为查询条件时,GROM只会查询非零值字段,意味着字段值为0,false或其他零值,该字段不会被用于构建查询条件,会使用map来构建查询条件
此时Users为结构体
*/
//SELECT * FROM users WHERE name = "jinzhu" 并不会查询到age=0的条件
db.Where(&Users{name:"jinzhu",Age:0}).Find(&users)
//SELECT * FROM users WHEERE name = "jinzhu" AND age = 0
db.where(map[string]interface{}{"name":"jinzhu","Age":0}).Find(&users)
- 更新数据
//条件更新单个列
//UPDATE users SET name='hello',update_at='XXXX-XX-XX XX:XX:XX' WHERE age>18
db.Model(&User{ID:111}).Where("age > ?",18).Update("name","hello")
//更新多个列,根据struct 更新属性,只会更新非零值的字段
//UPDATE users SET name="hello",age=18,updated_at='XXXX-XX-XX XX:XX:XX' WHERE id=111
db.Model(&User{ID:111}).Updates(User{Name:"hello",Age:18})
//根据map更新属性
//UPDATE users SET name="hello",age=18,actived=false,updated_at='XXXX-XX-XX XX:XX:XX' WHERE id=111
db.Model(&User{ID:111}).Updates(map[string]interface{{"name":"hello","age":18,"actived":false})
//更新选定字段
//UPDATE users SET name='hello' WHERE id=111
db.Model(&User{ID:111}).Select("name").Updates(map[string]interface{{"name":"hello","age":18,"actived":false})
//SQL表达式更新
//UPDATE "products" SET "age"=age*2+100,"updated_at"='XXXX-XX-XX XX:XX:XX' WHERE "id"=3
db.Model(&User{ID:3}).Update("age",gorm.Expr("age * ? + ?",2,100))
- 删除数据
- 物理删除
//DELET FROM users WHERE id=10
db.Delete(&User{},10)
//DELET FROM users WHERE id=10
db.Delete(&User{},"10")
//DELET FROM users WHERE id IN (1,2,3)
db.Delete(&User{},[]int{1,2,3})
//DELET FROM users WHERE name LIKE "%jinzhu%"
db.Where("name LIKE ?","%jinzhu%").Delete(User{})
//DELET FROM users WHERE name LIKE "%jinzhu%"
db.Delete(User{},"name LIKE ?","%jinzhu%")
- 软删除
拥有软删除能力的Model调用Delete时,记录不会被从数据库中真正删除,但是GORM会将DeletedAt置为当前时间,并且不能通过正常的查询方法找到该记录,但可以使用Unscoped查询到被软删除的数据
db.Where("age=?",20).Delete(&User{})
users:=make([]*User,0)
//在查询时会忽略被软删除的记录
db.where("age = ?",20).Find(&users)
//在查询时不会忽略被软删除的记录
db.Unscoped().Where("age = ?",20).Find(&users)