todo gorm

建立连接 & 建表

package main

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"time"
)

func main(){

	//建立连接:https://gorm.cn/zh_CN/docs/connecting_to_the_database.html

	//基础用法
	//dsn := "root:12345678@tcp(127.0.0.1:3306)/gorm_db?charset=utf8mb4&parseTime=True&loc=Local"
	//db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	//常用
	db,err:=gorm.Open(mysql.New(mysql.Config{
		DSN: "root:12345678@tcp(127.0.0.1:3306)/gorm_db?charset=utf8mb4&parseTime=True&loc=Local",
		DefaultStringSize: 171,
	}),&gorm.Config{
		//配置参考文档:https://gorm.cn/zh_CN/docs/gorm_config.html
		 SkipDefaultTransaction: false,//是否跳过默认事务
		 NamingStrategy: schema.NamingStrategy{
			 TablePrefix: "t_",   // 表名前缀,`User` 的表名应该是 `t_users`
			 SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
		 },
		 DisableForeignKeyConstraintWhenMigrating: true,//是否禁用外键约束
	})

	//设置连接池
	sqlDB, err := db.DB()
	sqlDB.SetMaxIdleConns(10)//设置空闲连接池中连接的最大数量
	sqlDB.SetMaxOpenConns(100)//设置打开数据库连接的最大数量
	sqlDB.SetConnMaxLifetime(time.Hour)//设置了连接可复用的最大时间

	type User struct {
		Name string
	}

	//_=db.AutoMigrate(&User{})//往数据库建表,t_user表

	M:=db.Migrator()
	//M.CreateTable(&User{})//往数据库建表,t_user表
	//fmt.Println(M.HasTable(&User{}))//判断是否存在&User{}对应表
	//fmt.Println(M.HasTable("t_user"))//判断是否存在t_user表
	//fmt.Println(M.DropTable(&User{}))//删除&User{}对应表
	if M.HasTable(&User{}){
		M.RenameTable(&User{},"t_user_2")//重命名表
	}else {
		M.CreateTable(&User{})
	}

	//以上操作可以类似地操作列


	fmt.Println(db,err)
}

gorm 模型

模型定义:Models are normal structs with basic Go types, pointers/alias of them or custom types implementing Scanner and Valuer interfaces

gorm约定

官方文档
GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间

主程序:

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"time"
)

var GLOBAL_DB *gorm.DB

func main(){

	//建立连接:https://gorm.cn/zh_CN/docs/connecting_to_the_database.html

	//基础用法
	//dsn := "root:12345678@tcp(127.0.0.1:3306)/gorm_db?charset=utf8mb4&parseTime=True&loc=Local"
	//db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	//常用
	db,_:=gorm.Open(mysql.New(mysql.Config{
		DSN: "root:12345678@tcp(127.0.0.1:3306)/gorm_db?charset=utf8mb4&parseTime=True&loc=Local",
		DefaultStringSize: 171,
	}),&gorm.Config{
		//配置参考文档:https://gorm.cn/zh_CN/docs/gorm_config.html
		 SkipDefaultTransaction: false,//是否跳过默认事务
		 NamingStrategy: schema.NamingStrategy{
			 TablePrefix: "t_",   // 表名前缀,`User` 的表名应该是 `t_users`
			 SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
		 },
		 DisableForeignKeyConstraintWhenMigrating: true,//是否禁用外键约束
	})

	//设置连接池
	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(10)//设置空闲连接池中连接的最大数量
	sqlDB.SetMaxOpenConns(100)//设置打开数据库连接的最大数量
	sqlDB.SetConnMaxLifetime(time.Hour)//设置了连接可复用的最大时间

	GLOBAL_DB=db

	TestUserCreate()
}

表模型

package main

import (
	"database/sql"
	"time"
)

type TestUser struct {
	ID           uint //约定:id会自动作为主键
	Name         string
	Email        *string
	Age          uint8
	Birthday     *time.Time
	MemberNumber sql.NullString
	ActivedAt    sql.NullTime
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

//type TestUser2 struct {
//	gorm.Model //包含了id、CreatedAt、UpdatedAt、DeletedAt
//	Name         string
//	Email        *string
//	Age          uint8
//	Birthday     *time.Time
//	MemberNumber sql.NullString
//	ActivedAt    sql.NullTime
//
//}
// gorm.Model 的定义
//type Model struct {
//	ID        uint           `gorm:"primaryKey"`
//	CreatedAt time.Time
//	UpdatedAt time.Time
//	DeletedAt gorm.DeletedAt `gorm:"index"`
//}

//gorm标签使用
//自定义Model
type Model struct {
	ID   uint `gorm:"primaryKey"` //设置为主键
	Time time.Time `gorm:"column:my_time"` //column:设置表中列名称
	//其他标签参考文档:https://gorm.cn/zh_CN/docs/models.html,"字段标签"处
}
type TestUser3 struct {
	Model
	Name         string
	Email        *string
	Age          uint8
	Birthday     *time.Time
	MemberNumber sql.NullString
}

func TestUserCreate() {
	GLOBAL_DB.AutoMigrate(&TestUser3{})
}

CRUD

package main

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"time"
)

var GLOBAL_DB *gorm.DB

func main(){
	db,_:=gorm.Open(mysql.New(mysql.Config{
		DSN: "root:12345678@tcp(127.0.0.1:3306)/gorm_db?charset=utf8mb4&parseTime=True&loc=Local",
		DefaultStringSize: 171,
	}),&gorm.Config{
		//配置参考文档:https://gorm.cn/zh_CN/docs/gorm_config.html
		 SkipDefaultTransaction: false,//是否跳过默认事务
		 NamingStrategy: schema.NamingStrategy{
			 TablePrefix: "t_",   // 表名前缀,`User` 的表名应该是 `t_users`
			 SingularTable: true, // 使用单数表名,启用该选项,此时,`User` 的表名应该是 `t_user`
		 },
		 DisableForeignKeyConstraintWhenMigrating: true,//是否禁用外键约束
	})

	//设置连接池
	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(10)//设置空闲连接池中连接的最大数量
	sqlDB.SetMaxOpenConns(100)//设置打开数据库连接的最大数量
	sqlDB.SetConnMaxLifetime(time.Hour)//设置了连接可复用的最大时间

	GLOBAL_DB=db

	//TestUserCreate()
	//CreatedTest()
	//FindTest()
	//UpdateTest()
	//DeleteTest()
	RawSQL()
}

CRUD

package main

import "fmt"

// CreatedTest 新增记录
// 创建记录文档:https://gorm.cn/zh_CN/docs/create.html
func CreatedTest(){
	//dbres := GLOBAL_DB.Create(&TestUser{
	//	Name: "Kramer",
	//	Age:  24,
	//})
	//_= GLOBAL_DB.Select("Name").Create(&TestUser{ //Select:创建只含有name的记录
	//	Name: "Kramer",
	//	Age:  24,
	//})
	//_= GLOBAL_DB.Omit("Name").Create(&TestUser{//Omit:创建不含name的记录,但是有默认值会赋值默认值
	//	Name: "Kramer",
	//	Age:  24,
	//})

	//批量创建,使用切片
	dbres:= GLOBAL_DB.Create(&[]TestUser{//Omit:创建不含name的记录,但是有默认值会赋值默认值
		{Name: "Kramer1", Age:  24},
		{Name: "Kramer2", Age:  25},
		{Name: "Kramer3", Age:  26},
		{Name: "Kramer4", Age:  27},
	})

	fmt.Println(dbres.Error,dbres.RowsAffected)//报错信息和影响记录条数
}

// FindTest 查询记录。接受返回值形式:Map、结构体(主要)
// 查询记录文档:https://gorm.cn/zh_CN/docs/query.html
func FindTest(){
	//var result map[string]interface{} go 1.17之后可以这么写
	//var result =map[string]interface{}{} //go 1.17之前这么写
	//GLOBAL_DB.Model(&TestUser{}).First(&result) //现有模型才能查第一个

	var user TestUser
	//var result =map[string]interface{}{} //where查询的时候First的参数不能是map了
	//GLOBAL_DB.Where("name <> ?", "Kramer").First(&user)//where参数为字符串
	//GLOBAL_DB.Where(TestUser{Name: "Kramer"}).First(&user)//where参数为结构体
	GLOBAL_DB.Where(map[string]interface{}{"name":"Kramer"}).First(&user)//where参数为map
	//fmt.Println(user)

	//批量查询
	var users []TestUser
	GLOBAL_DB.Find(&users,"name = ?","Kramer")//这里使用额内联

	//查询指定字段
	var users2 []TestUser
	GLOBAL_DB.Select("age").Find(&users2,"name = ?","Kramer")//这里使用额内联

	//查询之后放到别的结构体中,
	type UserInfo struct {
		Name       string
		Age        uint8
	}
	var userInfo UserInfo
	GLOBAL_DB.Model(&TestUser{}).Where("name = ?","Kramer1").Find(&userInfo)//这里Model指定与表对应的结构体,Find存放查询结果
	fmt.Println(userInfo)
}

// UpdateTest 更新记录
// 更新记录文档:https://gorm.cn/zh_CN/docs/update.html
func UpdateTest(){
	//update   更新单个列
	//updates  更新多列,Updates 方法支持 struct 和 map[string]interface{} 参数
	//save    无论如何都更新,会保存所有的字段,即使字段是零值

	//GLOBAL_DB.Model(&TestUser{}).Where("name=?","Kramer").Update("age",10)

	//save需要根据主键更新
	//var users []TestUser
	//dbRes:=GLOBAL_DB.Where("name=?","Kramer").Find(&users)
	//for k,_ := range users{
	//	users[k].Age=15
	//}
	//dbRes.Save(users)

	//先选出记录,再更新
	var users []TestUser
	GLOBAL_DB.Find(&users).Updates(map[string]interface{}{"Name":"","age":0})
	var user TestUser
	GLOBAL_DB.Find(&user).Updates(TestUser{Name: "",Age: 0})//Updates以结构体更新时,不会操作0值,也就是本次操作不会更新
}

// DeleteTest 删除记录
// 删除记录文档:https://gorm.cn/zh_CN/docs/delete.html
func DeleteTest()  {
	var user TestUser
	GLOBAL_DB.Where("name=?","").Delete(&user)//软删除
	GLOBAL_DB.Unscoped().Where("name=?","").Delete(&user)//删除记录

}

// RawSQL 原生SQL
// 原生SQL文档:https://gorm.cn/zh_CN/docs/sql_builder.html
func RawSQL()  {
	var user TestUser
	GLOBAL_DB.Raw("select id ,name from t_test_user where id =1").Scan(&user)
	fmt.Println(user)
}

model

package main

import (
	"gorm.io/gorm"
)

type TestUser struct {
	gorm.Model //包含了id、CreatedAt、UpdatedAt、DeletedAt
	Name       string
	Age        uint8
}

func TestUserCreate() {
	GLOBAL_DB.AutoMigrate(&TestUser{})
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值