跳到主要内容

Gorm中修改mysql主键的方法

一、为什么要修改mysql主键策略

1、我们创建mysql数据表的时候正常操作都是采用id自增类型,但是往往会造成以下几个问题 让别人可以猜到你数据库的数据量多少,甚至可以根据当前看到的id可以手动的修改浏览器上id来访问下一条数据 如果分表后会造成主键id是一样的 2、正常的做法可以修改mysql主键策略 直接使用uuid来作为主键,但是这样不好的地方是无序的,不会根据从前往后排列 使用雪花算法生成一个唯一的id

二、gorm中修改mysql表主键的方法

1、直接使用数据表的hook方法,官网地址,直接在hook里面修改主键的值 2、使用gorm插件的方式全局修改,官网地址,官网上的案例似乎有点问题,自行验证

三、使用gorm插件来自定义主键

1、选用的雪花算法第三方库,链接地址

2、创建一个plugin.go的文件,我也不废话,直接贴上我自己定义的代码

package common

import (
"fmt"
"gin-admin-api/utils"
"github.com/bwmarrin/snowflake"
"gorm.io/gorm"
)

type DbFieldPlugin struct{}

func (op *DbFieldPlugin) Name() string {
return "dbFieldPlugin"
}

func (op *DbFieldPlugin) Initialize(db *gorm.DB) (err error) {
// 创建字段的时候雪花算法生成id
db.Callback().Create().Before("gorm:create").Replace("id", func(db *gorm.DB) {
node, _ := snowflake.NewNode(1)
id := node.Generate()
db.Statement.SetColumn("id", fmt.Sprintf("%d", id))
accountId := db.Statement.Context.Value("accountId")
//fmt.Println(accountId, "????")
db.Statement.SetColumn("created_by", accountId)
})
// 创建人
db.Callback().Create().Before("gorm:create").Replace("created_by", func(db *gorm.DB) {
if db.Statement.Schema != nil {
fmt.Println("创建的钩子函数")
// 获取到上下文中数据
accountId := db.Statement.Context.Value("accountId")
fmt.Println(accountId, "????")
db.Statement.SetColumn("created_by", accountId)
}
})
// 更新人
db.Callback().Update().Before("gorm:before_update").Replace("updated_by", func(db *gorm.DB) {
if db.Statement.Schema != nil {
fmt.Println("修改")
accountId := db.Statement.Context.Value("accountId")
db.Statement.SetColumn("updated_by", accountId)
}
})
db.Callback().Update().Before("gorm:after_update").Replace("updated_by1", func(db *gorm.DB) {
fmt.Println("更新后")
fmt.Println(db.Statement.Model, "当前数据11")
fmt.Println(utils.MapToJson(db.Statement.Dest), "当前数据21")
})
// 删除人
db.Callback().Delete().Before("gorm:delete").Replace("deleted_by", func(db *gorm.DB) {
if db.Statement.Schema != nil {
accountId := db.Statement.Context.Value("accountId")
fmt.Println("删除1111", accountId)
db.Statement.SetColumn("deleted_by", accountId)
}
})
return
}

3、使用插件

db.Use(&DbFieldPlugin{})