一、简单的对gorm
的封装使用
-
1、下载依赖包
go get -u gorm.io/gorm gorm.io/driver/mysql
-
2、在
utils
的文件夹下封装一个数据库的连接方法package utils import ( "fmt" _ "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" "gorm.io/gorm/schema" ) var GormDb *gorm.DB func init() { var err error sqlStr := "root:123456@tcp(localhost:3306)/beego?charset=utf8mb4&parseTime=true&loc=Local" // 关于配置可以参考 https://gorm.io/zh_CN/docs/gorm_config.html GormDb, err = gorm.Open(mysql.Open(sqlStr), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), //DisableForeignKeyConstraintWhenMigrating: true, // 禁止创建外键 NamingStrategy: schema.NamingStrategy{ // 给创建表时候使用的 SingularTable: true, // 全部的表名前面加前缀 //TablePrefix: "mall_", }, }) if err != nil { fmt.Println("数据库连接错误", err) return } }
-
3、封装一个将
map
转换为字符串的方法import "encoding/json" func MapToJson(data interface{}) string { byteStr, _ := json.Marshal(data) return string(byteStr) }
二、一对一的关联关系
-
1、参考文档,建议大家先阅读文档
-
2、这里就不使用官网案例,直接使用用户和身份证号码的两个表来举例,一个用户只有一个身份证号码,一个身份证号码也只能属于一个用户
-
3、创建数据模型并且自动映射生成到数据库中
type UserEntity struct { Id int `json:"id" gorm:"type:int(11);autoIncrement;primaryKey;column:id;"` // 主键id Name string `json:"name" gorm:"type:varchar(30);not null;"` //姓名 Age int `json:"age" gorm:"type:int(11);default:0;"` } type IdCardEntity struct { Id int `json:"id" gorm:"type:int(11);autoIncrement;primaryKey;column:id;"` // 主键id No string `json:"no" gorm:"type:varchar(20);not null;"` // 身份证号码 //外键关联到用户表 User UserEntity `json:"user"` UserId int `json:"user_id"` } func (UserEntity) TableName() string { return "user" } func (IdCardEntity) TableName() string { return "id_card" } func init() { utils.GormDb.AutoMigrate(&UserEntity{}, &IdCardEntity{}) }
-
4、映射生成的数据表结构如下
-- 用户表的数据结构 +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | <null> | | | name | varchar(30) | NO | | <null> | | | age | int(11) | YES | | 0 | | +-------+-------------+------+-----+---------+-------+ -- 身份证表 +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | <null> | | | no | varchar(20) | NO | | <null> | | | user_id | int(11) | YES | MUL | <null> | | +---------+-------------+------+-----+---------+-------+
-
5、使用
Joins
的方式连表的方式查询用户及身份证号码出来var userListEntity []map[string]interface{} utils.GormDb.Model(&UserEntity{}).Select("user.id", "user.name", "user.age", "id_card.no"). Joins("left join id_card on user.id = id_card.user_id").Scan(&userListEntity) fmt.Println(tools.MapToJson(userListEntity))
[{"age":10,"id":1,"name":"张三","no":"110"}]
-
6、使用
Preload
反向在身份证表中去查询用户信息var idCardListEntity []IdCardEntity utils.GormDb.Preload("User").Find(&idCardListEntity) fmt.Println(tools.MapToJson(idCardListEntity))
[{"id":1,"no":"110","user":{"id":1,"name":"张三","age":10},"user_id":1}]
三、一对多的关联关系
-
1、官网地址,自行观看官网内容
-
2、这里我们举例班级和学生的关联关系,一个班级有多个学生,学生只能属于一个班级的案例
-
3、创建数据模型
type ClassEntity struct { Id int `json:"id" gorm:"type:int(11);autoIncrement;primaryKey;column:id;` Name string `json:"name"` // 一个班级中有多个学生foreignKey表示外键关联的字段 StudentList []*StudentEntity `json:"student_list" gorm:"foreignKey:ClassId"` } type StudentEntity struct { Id int `json:"id" gorm:"type:int(11);autoIncrement;primaryKey;column:id;` Name string `json:"name"` // 外键关联到班级表的数据模型 ClassId int `json:"class_id"` } func (StudentEntity) TableName() string { return "student" } func (ClassEntity) TableName() string { return "class" } func init() { utils.GormDb.AutoMigrate(&ClassEntity{}, &StudentEntity{}) }
-
4、自己手动插入数据
-
5、查询班级列表并且查询全部的学生出来
var classList []ClassEntity utils.GormDb.Preload("StudentList").Find(&classList) fmt.Println(tools.MapToJson(classList))
[{"id":1,"name":"班级一","student_list":[{"id":1,"name":"学生一","class_id":1},{"id":2,"name":"学生二","class_id":1}]}]
-
6、查询学生想顺带查询出班级
-
学生表上添加一个字段(直接添加就可以)
type StudentEntity struct { Id int `json:"id"` Name string `json:"name"` + Class ClassEntity `json:"class"` // 需要反向查询的时候加上 ClassId int `json:"class_id"` }
-
查询数据
var studentList []StudentEntity utils.GormDb.Joins("Class").Find(&studentList) fmt.Println(tools.MapToJson(studentList))
[{"id":1,"name":"学生一","class":{"id":1,"name":"班级一","student_list":null},"class_id":1},{"id":2,"name":"学生二","class":{"id":1,"name":"班级一","student_list":null},"class_id":1}]
-
四、多对多的关联关系
-
1、官网地址
-
2、我们这里举例账号和角色的关联关系,一个账号可以有多个角色,一个角色也可以给多个账号的关系
-
3、定义数据模型
type AccountEntity struct { Id int `json:"id"` Name string `json:"name"` Roles []*RoleEntity `json:"roles" gorm:"many2many:account_role;foreignKey:Id;joinForeignKey:accountId;joinReferences:roleId;"` } type RoleEntity struct { Id int `json:"id"` Title string `json:"title"` Accounts []*AccountEntity `json:"accounts" gorm:"many2many:account_role;foreignKey:Id;joinForeignKey:roleId;joinReferences:accountId"` } func (AccountEntity) TableName() string { return "account" } func (RoleEntity) TableName() string { return "role" } func init() { utils.GormDb.AutoMigrate(&AccountEntity{}, &RoleEntity{}) }
-
4、上面几个用到的字段解析说明,官网介绍地址
many2many:user_profiles
定义中间表名为:user_profiles
foreignKey
:Id
使用当前表的id
作为外键joinForeignKey:accountId
当前数据模型外键关联到中间件表的字段名叫accountId
joinReferences:roleId
反向引用字段,如果是账号表就要写中间表的roleId
-
5、手动添加数据库
-
6、查找账号列表顺便查询出角色信息
var accountList []AccountEntity utils.GormDb.Preload("Roles").Find(&accountList) fmt.Println(tools.MapToJson(accountList))
[ { "id":1, "name":"账号一", "roles":[ {"id":1,"title":"角色一","accounts":null}, {"id":2,"title":"角色二","accounts":null} ] }, { "id":2, "name":"账号二", "roles":[ {"id":1,"title":"角色一","accounts":null} ] } ]
-
7、根据角色查询到账号信息
var roleList []RoleEntity utils.GormDb.Preload("Accounts").Find(&roleList) fmt.Println(tools.MapToJson(roleList))
[ { "id":1, "title":"角色一", "accounts":[ {"id":1,"name":"账号一","roles":null}, {"id":2,"name":"账号二","roles":null} ] }, { "id":2, "title":"角色二", "accounts":[ {"id":1,"name":"账号一","roles":null} ] } ]
五、数据模型
上面仅仅是演示使用关于数据模型的完善需要自己参考官网,链接地址