1,gorm介绍
1.1,什么是orm?
Object-Relationl Mapping,即对象关系映射,这里的Relationl指的是关系型数据库
它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
1.2,gorm
1.Golang写的,GitHub上活跃度很高的orm库
2.特点:
全功能ORM;
关联(包含一个,包含多个,属于,多对多,多种包含);
Callbacks(创建/保存/更新/删除/查找之前/之后);
预加载;
事务
复合主键
SQL Builder
自动迁移
日志
可扩展,编写基于GORM回调的插件
每个功能都有测试
开发人员友好
1.3,安装
go get github.com/jinzhu/gorm
1.4 ,官方文档:
http://gorm.book.jasperxu.com/
2,基本用法
2.1,新建 GlobalVariabel.go 保存全局变量
package variable
import "gorm.io/gorm"
var GLOBAL_DB *gorm.DB
2.2,新建 main
package main
import (
"go_gorm/src/config"
"go_gorm/src/demo03_crud/model"
"go_gorm/src/entity/variable"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"time"
)
func main() {
configInfo := config.InitConf()
db,_ := gorm.Open(mysql.New(mysql.Config{
DriverName: "",
ServerVersion: "",
DSN: configInfo.MysqlUrl,
DSNConfig: nil,
Conn: nil,
SkipInitializeWithVersion: false,
DefaultStringSize: 174,
DefaultDatetimePrecision: nil,
DisableWithReturning: false,
DisableDatetimePrecision: false, //是否禁用datetime精度
DontSupportRenameIndex: false, //是否重命名索引时采用删除并新建的方式
DontSupportRenameColumn: false,
DontSupportForShareClause: false,
DontSupportNullAsDefaultValue: false,
}),&gorm.Config{
SkipDefaultTransaction: false,
FullSaveAssociations: false,
Logger: nil,
NowFunc: nil,
DryRun: false,
PrepareStmt: false,
DisableAutomaticPing: false,
DisableForeignKeyConstraintWhenMigrating: true,
DisableNestedTransaction: false,
AllowGlobalUpdate: false,
QueryFields: false,
CreateBatchSize: 0,
ClauseBuilders: nil,
ConnPool: nil,
Dialector: nil,
Plugins: nil,
})
sqlDB,_:=db.DB()
sqlDB.SetMaxIdleConns(10) //连接池中最大空闲连接数
sqlDB.SetMaxOpenConns(100) //连接池最多容纳数量
sqlDB.SetConnMaxLifetime(time.Hour)//连接池中连接最大可复用时间
variable.GLOBAL_DB = db
//建表
model.TestUserCreate()
//插入数据
//insert()
//查询数据
//search()
//更新操作
//update()
//删除
//delete()
//原生sql
Sql()
}
func Sql() {
model.SqlDemo01()
}
func delete() {
//软删除 数据库中deleted_at字段有值
//model.DeleteDemo01()
//真实删除
//model.DeleteDemo02()
}
func update() {
//更新选中的字段
//model.UpdateDemo01()
//使用save更新 (不常用)
//model.UpdateDemo02()
//使用updates已结构体更新 ,以strcut更新多列时结构体中的零值不参与更新
//model.UpdateDemo03()
//使用updates以map更新
//model.UpdateDemo04()
}
func search() {
//根据索引查询第一条 以map接收
//model.SearchDemo01()
//根据索引查询第一条 以结构体接收
//model.SearchDemo02()
//根据索引查询最后一条 以结构体接收
//model.SearchDemo03()
//根据主键查询 以结构体接收
//model.SearchDemo04()
//按条件查询以结构体接收
//model.SearchDemo05()
//按条件查询(已结构体),以结构体接收
//model.SearchDemo06()
// or条件查询,以结构体接收
//model.SearchDemo07()
//查多条
//model.SearchDemo08()
//智能选择字段
//model.SearchDemo09()
}
func insert() {
//插入数据
//model.TestUserInsertDemo01()
//model.TestUserInsertDemo02()
//model.TestUserInsertDemo03()
//model.TestUserInsertDemo04()
}
2.3,(删除)新建 modelDelete
package model
import (
"errors"
"fmt"
"go_gorm/src/entity/model"
"go_gorm/src/entity/variable"
"gorm.io/gorm"
"log"
)
//软删除 数据库中deleted_at字段有值
func DeleteDemo01() {
var user []model.TestUser
dbRes := variable.GLOBAL_DB.
Where("name like ?","%李乃龙%").
Delete(&user)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,删除失败")
}else{
fmt.Println("删除成功")
}
}
//真实删除
func DeleteDemo02() {
var user []model.TestUser
dbRes := variable.GLOBAL_DB.
Unscoped().
Where("name like ?","%李乃龙%").
Delete(&user)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,删除失败")
}else{
fmt.Println("删除成功")
}
}
2.4,(新增)新建 modelInsert
package model
import (
"fmt"
"go_gorm/src/entity/model"
"go_gorm/src/entity/variable"
)
//建表
func TestUserCreate() {
variable.GLOBAL_DB.AutoMigrate(&model.TestUser{})
}
//插入数据
func TestUserInsertDemo01() {
dbres := variable.GLOBAL_DB.Create(&model.TestUser{
Name: "李乃龙",
Age: 25,
})
fmt.Println("是否报错:",dbres.Error)
fmt.Println("影响条数:",dbres.RowsAffected)
}
//只创建name不创建age
func TestUserInsertDemo02() {
dbres := variable.GLOBAL_DB.Select("Name").Create(&model.TestUser{
Name: "李乃龙2",
Age: 23,
})
fmt.Println("是否报错:",dbres.Error)
fmt.Println("影响条数:",dbres.RowsAffected)
}
//创建name之外的字段
func TestUserInsertDemo03() {
dbres := variable.GLOBAL_DB.Omit("Name").Create(&model.TestUser{
Name: "李乃龙2",
Age: 23,
})
fmt.Println("是否报错:",dbres.Error)
fmt.Println("影响条数:",dbres.RowsAffected)
}
//批量添加
func TestUserInsertDemo04() {
dbres := variable.GLOBAL_DB.Create(&[]model.TestUser{
{
Name: "刘娟1",
Age: 25,
},
{
Name: "刘娟2",
Age: 25,
},
{
Name: "刘娟3",
Age: 25,
},
{
Name: "刘娟4",
Age: 25,
},
})
fmt.Println("是否报错:",dbres.Error)
fmt.Println("影响条数:",dbres.RowsAffected)
}
2.5,(查询)新建 modelSearch
package model
import (
"errors"
"fmt"
"go_gorm/src/entity/model"
"go_gorm/src/entity/variable"
"go_gorm/src/entity/vo"
"gorm.io/gorm"
"log"
)
/**
根据索引查询第一条 以map接收
*/
func SearchDemo01() {
var result map[string]interface{}
variable.GLOBAL_DB.Model(&model.TestUser{}).Find(&result)
fmt.Println(result)
}
/**
根据索引查询第一条 以结构体接收
*/
func SearchDemo02() {
var User model.TestUser
variable.GLOBAL_DB.Model(&model.TestUser{}).Find(&User)
fmt.Println(User)
}
/**
根据索引查询最后一条 以结构体接收
*/
func SearchDemo03() {
var User model.TestUser
variable.GLOBAL_DB.Model(&model.TestUser{}).Last(&User)
fmt.Println(User)
}
/**
根据主键查询 以结构体接收
*/
func SearchDemo04() {
var User model.TestUser
dbRes := variable.GLOBAL_DB.Model(&model.TestUser{}).Last(&User,44)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
}
/**
按条件查询以结构体接收
*/
func SearchDemo05() {
var User model.TestUser
dbRes := variable.GLOBAL_DB.Table("test_users").Where("name = ?","刘娟1").Last(&User)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查到数据")
}else{
fmt.Println(User.Name)
}
}
/**
按条件查询(已结构体),以结构体接收
*/
func SearchDemo06() {
var User model.TestUser
dbRes := variable.GLOBAL_DB.Table("test_users").Where("name = ?","刘娟1").Last(&User)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查到数据")
}else{
fmt.Println(User.Name)
}
}
/**
or条件查询,以结构体接收
*/
func SearchDemo07() {
var User model.TestUser
dbRes := variable.GLOBAL_DB.Table("test_users").
Where("name = ? AND age = ?","刘娟1",27).
Or("name = ?","刘娟2").
Last(&User)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查到数据")
}else{
fmt.Println(User.Name)
}
}
/**
查多条
*/
func SearchDemo08() {
var User []model.TestUser
dbRes := variable.GLOBAL_DB.Table("test_users").
Omit("age").
Where("name LIKE ?","%刘娟%").
Find(&User)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查到数据")
}else{
fmt.Println(User)
}
}
/**
智能选择字段
*/
func SearchDemo09() {
var UserVo[] vo.UserVo
dbRes := variable.GLOBAL_DB.Table("test_users").
Where("name LIKE ?","%刘娟%").
Find(&UserVo)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查到数据")
}else{
fmt.Println(UserVo)
}
}
2.6,(原生sql)新建 modelSql
package model
import (
"errors"
"fmt"
"go_gorm/src/entity/model"
"go_gorm/src/entity/variable"
"gorm.io/gorm"
"log"
)
func SqlDemo01() {
var user []model.TestUser
dbRes := variable.GLOBAL_DB.
Raw("SELECT id,created_at,updated_at,deleted_at,name,age FROM test_users").
Scan(&user)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据")
}else{
fmt.Println("询到成功",user)
}
}
2.6,(编辑)新建 modelUpdate
package model
import (
"errors"
"fmt"
"go_gorm/src/entity/model"
"go_gorm/src/entity/variable"
"gorm.io/gorm"
"log"
)
//update 只更新选择的字段
//updates 更新所有字段 此时有两种形式 map strcut 以strcut更新多列时结构体中的零值不参与更新
//save 无论如何都更新,所有内容包括0 save根据主键更新,没有主键会执行insert
//更新选中的字段
func UpdateDemo01() {
dbRes := variable.GLOBAL_DB.Table("test_users").
Where("name LIKE ?","%刘娟%").
Update("name","刘娟小宝宝").
Update("age",18)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,更新失败")
}else{
fmt.Println("更新成功")
}
}
//使用save更新 save根据主键更新,没有主键会执行insert
func UpdateDemo02() {
//dbRes := variable.GLOBAL_DB.Table("test_users").
// Where("name = ?","刘娟").
// Save(&model.TestUser{
// Name: "娟娟宝宝",
// })
var user []model.TestUser
dbRes := variable.GLOBAL_DB.Table("test_users").
Where("name = ?","刘娟").
Find(&user)
for i := range user {
user[i].Name = "娟宝宝" + string(i)
}
dbRes.Save(&user)
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,更新失败")
}else{
fmt.Println("更新成功")
}
}
//使用updates以结构体更新 ,以strcut更新多列时结构体中的零值不参与更新
func UpdateDemo03() {
var user model.TestUser
dbRes := variable.GLOBAL_DB.
Table("test_users").
First(&user).
Updates(model.TestUser{
Name: "更新第一条数据",
Age: 0,
})
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,更新失败")
}else{
fmt.Println("更新成功")
}
}
//使用updates以map更新
func UpdateDemo04() {
var user model.TestUser
dbRes := variable.GLOBAL_DB.
Table("test_users").
First(&user).
Updates(map[string]interface{}{
"name":"更新第一条数据2",
"age":0,
})
fmt.Println("error info:",dbRes.Error)
fmt.Println(errors.Is(dbRes.Error,gorm.ErrRecordNotFound))
if(errors.Is(dbRes.Error,gorm.ErrRecordNotFound)){
log.Println("没查询到数据,更新失败")
}else{
fmt.Println("更新成功")
}
}