golang 中使用gorm实现审计字段

利用gorm的callbacks实现审计字段,如创建、修改订单时自动保存创建人、修改人信息,但又不希望每个结构体中定义SetCreatedBy、SetUpdatedBy方法。开干

Callbacks简单介绍

GORM 自身也是基于 Callbacks 的,包括 CreateQueryUpdateDeleteRowRaw。此外,您也完全可以根据自己的意愿自定义 GORM

回调会注册到全局 *gorm.DB,而不是会话级别。如果您想要 *gorm.DB 具有不同的回调,您需要初始化另一个 *gorm.DB

详情见gorm官方文档,编写插件 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

实现我们自己的callback函数,比如想实现自动审计日志

1、创建一个autoAuditlog方法
func autoAuditLog(db *gorm.DB) {
    // 查找schema中是否包含CreatedBy字段
	createby := db.Statement.Schema.LookUpField("CreatedBy")
    // 如果没有则直接返回
	if createby == nil {
		return
	}
    // 登录鉴权后把个人信息存储到当前的Context中然后传递给相关数据库操作方法       
    // 把Context传递给*gorm.DB.WithContext, 然后就可以获取Context中的账号信息

	account := httpctx.GetAccount(db.Statement.Context)
    // 获取当前创建Model(表结构体)的反射数据
	data := db.Statement.ReflectValue
    // 这里需要判断一下是否为Slice, 如果切片则表示批量新增,所以进行for循环赋值 
	if data.Kind() == reflect.Slice {
		for i := 0; i < data.Len(); i++ {
            // 获取每个切片元素的所有element
			elem := data.Index(i)
            // 获取CreatedBy字段
			field := elem.FieldByName("CreatedBy")
            // 判断是否有效并且是否可以设置
			if field.IsValid() && field.CanSet() {
				field.SetString(account)
			}
		}
        // 通过return 结束该回调方法
		return
	}
    // 不是切片则直接修改CreatedBy的值
	db.Statement.SetColumn("CreatedBy", account)
}

2、在全局*gorm.DB中注册callback,Before表示在数据创建前注册一个autoAuditLog回调


var DbClient *gorm.DB

func ConnectToDB() {
	var err error
	dsn := "host=localhost user=postgres password=postgre dbname=my_test0910 port=5432 sslmode=disable TimeZone=Asia/Shanghai"
	DbClient, err = gorm.Open(postgres.Open(dsn), &gorm.Config{PrepareStmt: true, SkipDefaultTransaction: true})
    // 创建前注册autoAuditLog, 每次新增都会进行该回调处理
	DbClient.Callback().Create().Before("gorm:before_create").Register("update_create_by", autoAuditLog)
	if err != nil {
		slog.Error("postges sql connection failed", err)
		panic(err)
	}
}

至此完成了一个简单创建人的审计字段,大家可根据自己的业务需求实现自己想要的审计日志逻辑,这样即能省略了一大堆重复代码,也增强了代码的可维护性。如果各位大佬有更好的实现方式欢迎留言讨论。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值