From c5ca01eb47241d915808577d76c12f38f3286ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 18 Oct 2025 13:59:53 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=8D=87=E7=BA=A7BaseDao,=20?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=E6=B3=9B=E5=9E=8B=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base.go | 123 ++++++++------------------------------------------------ 1 file changed, 16 insertions(+), 107 deletions(-) diff --git a/base.go b/base.go index 8e5d675..b841dec 100644 --- a/base.go +++ b/base.go @@ -15,20 +15,12 @@ import ( ) // BaseDao 基础dao层 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 14:13 2023/2/9 -type BaseDao struct { +type BaseDao[DatabaseDataType any] struct { TableName string // 继承BaseDao,需要指定表名,后续调用不用传递表名进来,如果分表了,使用SetOption设置表名, 这里的优先级更高 } // Create 创建新的数据 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:06 下午 2021/8/8 -func (b *BaseDao) Create(dbInstance *gorm.DB, data any, optionList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType]) Create(dbInstance *gorm.DB, data *DatabaseDataType, optionList ...define.SetOption) error { o := &define.Option{} for _, itemFunc := range optionList { itemFunc(o) @@ -41,51 +33,29 @@ func (b *BaseDao) Create(dbInstance *gorm.DB, data any, optionList ...define.Set } // Update 更新数据 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:12 下午 2021/8/8 -func (b *BaseDao) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType]) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) r := dbInstance.Updates(updateData) return r.RowsAffected, r.Error } // UpdateOne 更新一条数据 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 17:05 2024/1/13 -func (b *BaseDao) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType]) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { optionFuncList = append(optionFuncList, WithLimit(1, 0)) return b.Update(dbInstance, updateData, optionFuncList...) } // List 查询数据列表 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:14 下午 2021/8/8 -func (b *BaseDao) List(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType]) List(dbInstance *gorm.DB, result []DatabaseDataType, optionFuncList ...define.SetOption) error { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) return dbInstance.Find(result).Error } // ListAndTotal 同时查询数据列表和数据总数 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 16:04 2025/2/26 -func (b *BaseDao) ListAndTotal(dbInstance *gorm.DB, listRes any, totalRes *int64, disableTotal bool, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType]) ListAndTotal(dbInstance *gorm.DB, listRes []DatabaseDataType, totalRes *int64, disableTotal bool, optionFuncList ...define.SetOption) error { var ( err error ) - if err = b.receiverTypeValid(listRes); nil != err { - return err - } - if err = b.receiverTypeValid(totalRes); nil != err { - return err - } dbInstance = b.setTxCondition(dbInstance, optionFuncList...) if err = dbInstance.Find(listRes).Error; nil != err { @@ -106,32 +76,20 @@ func (b *BaseDao) ListAndTotal(dbInstance *gorm.DB, listRes any, totalRes *int64 } // Delete 删除数据, 硬删除, 对应 delete语句 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 11:46 2023/2/9 -func (b *BaseDao) Delete(dbInstance *gorm.DB, dataModel any, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType]) Delete(dbInstance *gorm.DB, dataModel DatabaseDataType, optionFuncList ...define.SetOption) (int64, error) { dbInstance = dbInstance.Model(dataModel) dbInstance = b.setTxCondition(dbInstance, optionFuncList...).Delete(dataModel) return dbInstance.RowsAffected, dbInstance.Error } // Detail 查询详情 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:25 下午 2021/8/8 -func (b *BaseDao) Detail(dbInstance *gorm.DB, result any, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType]) Detail(dbInstance *gorm.DB, result *DatabaseDataType, optionFuncList ...define.SetOption) error { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) return dbInstance.First(result).Error } // DetailByPrimaryID ... -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 14:14 2023/10/15 -func (b *BaseDao) DetailByPrimaryID(dbInstance *gorm.DB, result any, primaryID any, primaryKey ...string) error { +func (b *BaseDao[DatabaseDataType]) DetailByPrimaryID(dbInstance *gorm.DB, result *DatabaseDataType, primaryID any, primaryKey ...string) error { primaryKeyField := "id" if len(primaryKey) > 0 { primaryKeyField = primaryKey[0] @@ -142,20 +100,12 @@ func (b *BaseDao) DetailByPrimaryID(dbInstance *gorm.DB, result any, primaryID a } // IsNotFound 增加结果是否为数据不存在的判断 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 15:57 2023/2/23 -func (b *BaseDao) IsNotFound(err error) bool { +func (b *BaseDao[DatabaseDataType]) IsNotFound(err error) bool { return errors.Is(err, gorm.ErrRecordNotFound) } // Count 查询数量 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 8:25 下午 2021/8/8 -func (b *BaseDao) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType]) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) { optionFuncList = append(optionFuncList, WithClearLimit()) dbInstance = b.setTxCondition(dbInstance, optionFuncList...) var cnt int64 @@ -163,11 +113,7 @@ func (b *BaseDao) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) } // Tx 执行事务 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 20:31 2022/12/24 -func (b *BaseDao) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error) error { +func (b *BaseDao[DatabaseDataType]) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error) error { if nil == dbInstance { return errors.New("db instance is null") } @@ -180,38 +126,22 @@ func (b *BaseDao) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error } // Begin 开启事务 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 3:09 下午 2021/8/9 -func (b *BaseDao) Begin(dbInstance *gorm.DB) *gorm.DB { +func (b *BaseDao[DatabaseDataType]) Begin(dbInstance *gorm.DB) *gorm.DB { return dbInstance.Begin() } // Commit 提交事务 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 3:10 下午 2021/8/9 -func (b *BaseDao) Commit(db *gorm.DB) error { +func (b *BaseDao[DatabaseDataType]) Commit(db *gorm.DB) error { return db.Commit().Error } // Rollback 回滚 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 3:12 下午 2021/8/9 -func (b *BaseDao) Rollback(db *gorm.DB) error { +func (b *BaseDao[DatabaseDataType]) Rollback(db *gorm.DB) error { return db.Rollback().Error } // setTxCondition 设置查询条件 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 17:38 2022/5/15 -func (b *BaseDao) setTxCondition(inputTx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB { +func (b *BaseDao[DatabaseDataType]) setTxCondition(inputTx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB { // 构建查询条件 o := &define.Option{} for _, fn := range optionFuncList { @@ -314,26 +244,5 @@ func (b *BaseDao) setTxCondition(inputTx *gorm.DB, optionFuncList ...define.SetO tx.Or(orSql, orBindVal) } } - /*sqlBlockList := make([]string, 0) - bindValueList := make([]any, 0) - sql, bindVal := optionToSql(o) - tx.Or(sql, bindVal...) - sqlBlockList = append(sqlBlockList, sql) - bindValueList = append(bindValueList, bindVal) - for _, itemOrFuncList := range o.OR { - orOption := &Option{} - for _, fn := range itemOrFuncList { - fn(orOption) - } - orSql, orBindVal := optionToSql(orOption) - tx.Or(orSql, orBindVal...) - }*/ return tx } - -func (b *BaseDao) receiverTypeValid(receiver any) error { - if receiver == nil || reflect.TypeOf(receiver).Kind() != reflect.Ptr { - return errors.New("receiver is nil or receiver is not a pointer") - } - return nil -} From 74026cf1ace79e375c305539da331e9e5f83f678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 18 Oct 2025 18:41:44 +0800 Subject: [PATCH 2/2] =?UTF-8?q?upgrade:=20=E5=8D=87=E7=BA=A7BaseDao,=20?= =?UTF-8?q?=E5=9F=BA=E4=BA=8E=E6=B3=9B=E5=9E=8B=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base.go | 94 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 21 deletions(-) diff --git a/base.go b/base.go index b841dec..5ffb4a1 100644 --- a/base.go +++ b/base.go @@ -14,45 +14,57 @@ import ( "gorm.io/gorm/clause" ) +func NewBaseDao[DatabaseDataType any, DatabaseTableColumns any]() *BaseDao[DatabaseDataType, DatabaseTableColumns] { + res := &BaseDao[DatabaseDataType, DatabaseTableColumns]{} + res.tableName = res.TableName() + res.columns = res.Columns() + res.isSetColumns = true + res.columnComment = res.ColumnComment() + return res +} + // BaseDao 基础dao层 -type BaseDao[DatabaseDataType any] struct { - TableName string // 继承BaseDao,需要指定表名,后续调用不用传递表名进来,如果分表了,使用SetOption设置表名, 这里的优先级更高 +type BaseDao[DatabaseDataType any, DatabaseTableColumns any] struct { + tableName string // 继承BaseDao,需要指定表名,后续调用不用传递表名进来,如果分表了,使用SetOption设置表名, 这里的优先级更高 + isSetColumns bool + columns DatabaseTableColumns + columnComment map[string]string } // Create 创建新的数据 -func (b *BaseDao[DatabaseDataType]) Create(dbInstance *gorm.DB, data *DatabaseDataType, optionList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Create(dbInstance *gorm.DB, data any, optionList ...define.SetOption) error { o := &define.Option{} for _, itemFunc := range optionList { itemFunc(o) } - tableName := b.TableName + useTableName := b.tableName if len(o.Table) > 0 { - tableName = o.Table + useTableName = o.Table } - return dbInstance.Table(tableName).Create(data).Error + return dbInstance.Table(useTableName).Create(data).Error } // Update 更新数据 -func (b *BaseDao[DatabaseDataType]) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Update(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) r := dbInstance.Updates(updateData) return r.RowsAffected, r.Error } // UpdateOne 更新一条数据 -func (b *BaseDao[DatabaseDataType]) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) UpdateOne(dbInstance *gorm.DB, updateData any, optionFuncList ...define.SetOption) (int64, error) { optionFuncList = append(optionFuncList, WithLimit(1, 0)) return b.Update(dbInstance, updateData, optionFuncList...) } // List 查询数据列表 -func (b *BaseDao[DatabaseDataType]) List(dbInstance *gorm.DB, result []DatabaseDataType, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) List(dbInstance *gorm.DB, result *[]*DatabaseDataType, optionFuncList ...define.SetOption) error { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) return dbInstance.Find(result).Error } // ListAndTotal 同时查询数据列表和数据总数 -func (b *BaseDao[DatabaseDataType]) ListAndTotal(dbInstance *gorm.DB, listRes []DatabaseDataType, totalRes *int64, disableTotal bool, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) ListAndTotal(dbInstance *gorm.DB, listRes *[]DatabaseDataType, totalRes *int64, disableTotal bool, optionFuncList ...define.SetOption) error { var ( err error ) @@ -76,20 +88,20 @@ func (b *BaseDao[DatabaseDataType]) ListAndTotal(dbInstance *gorm.DB, listRes [] } // Delete 删除数据, 硬删除, 对应 delete语句 -func (b *BaseDao[DatabaseDataType]) Delete(dbInstance *gorm.DB, dataModel DatabaseDataType, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Delete(dbInstance *gorm.DB, dataModel *DatabaseDataType, optionFuncList ...define.SetOption) (int64, error) { dbInstance = dbInstance.Model(dataModel) dbInstance = b.setTxCondition(dbInstance, optionFuncList...).Delete(dataModel) return dbInstance.RowsAffected, dbInstance.Error } // Detail 查询详情 -func (b *BaseDao[DatabaseDataType]) Detail(dbInstance *gorm.DB, result *DatabaseDataType, optionFuncList ...define.SetOption) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Detail(dbInstance *gorm.DB, result *DatabaseDataType, optionFuncList ...define.SetOption) error { dbInstance = b.setTxCondition(dbInstance, optionFuncList...) return dbInstance.First(result).Error } // DetailByPrimaryID ... -func (b *BaseDao[DatabaseDataType]) DetailByPrimaryID(dbInstance *gorm.DB, result *DatabaseDataType, primaryID any, primaryKey ...string) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) DetailByPrimaryID(dbInstance *gorm.DB, result *DatabaseDataType, primaryID any, primaryKey ...string) error { primaryKeyField := "id" if len(primaryKey) > 0 { primaryKeyField = primaryKey[0] @@ -100,12 +112,12 @@ func (b *BaseDao[DatabaseDataType]) DetailByPrimaryID(dbInstance *gorm.DB, resul } // IsNotFound 增加结果是否为数据不存在的判断 -func (b *BaseDao[DatabaseDataType]) IsNotFound(err error) bool { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) IsNotFound(err error) bool { return errors.Is(err, gorm.ErrRecordNotFound) } // Count 查询数量 -func (b *BaseDao[DatabaseDataType]) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Count(dbInstance *gorm.DB, optionFuncList ...define.SetOption) (int64, error) { optionFuncList = append(optionFuncList, WithClearLimit()) dbInstance = b.setTxCondition(dbInstance, optionFuncList...) var cnt int64 @@ -113,7 +125,7 @@ func (b *BaseDao[DatabaseDataType]) Count(dbInstance *gorm.DB, optionFuncList .. } // Tx 执行事务 -func (b *BaseDao[DatabaseDataType]) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Tx(dbInstance *gorm.DB, txFunc func(dbInstance *gorm.DB) error) error { if nil == dbInstance { return errors.New("db instance is null") } @@ -126,22 +138,22 @@ func (b *BaseDao[DatabaseDataType]) Tx(dbInstance *gorm.DB, txFunc func(dbInstan } // Begin 开启事务 -func (b *BaseDao[DatabaseDataType]) Begin(dbInstance *gorm.DB) *gorm.DB { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Begin(dbInstance *gorm.DB) *gorm.DB { return dbInstance.Begin() } // Commit 提交事务 -func (b *BaseDao[DatabaseDataType]) Commit(db *gorm.DB) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Commit(db *gorm.DB) error { return db.Commit().Error } // Rollback 回滚 -func (b *BaseDao[DatabaseDataType]) Rollback(db *gorm.DB) error { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Rollback(db *gorm.DB) error { return db.Rollback().Error } // setTxCondition 设置查询条件 -func (b *BaseDao[DatabaseDataType]) setTxCondition(inputTx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB { +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) setTxCondition(inputTx *gorm.DB, optionFuncList ...define.SetOption) *gorm.DB { // 构建查询条件 o := &define.Option{} for _, fn := range optionFuncList { @@ -157,7 +169,7 @@ func (b *BaseDao[DatabaseDataType]) setTxCondition(inputTx *gorm.DB, optionFuncL if len(o.Table) > 0 { tx = tx.Table(o.Table) } else { - tx = tx.Table(b.TableName) + tx = tx.Table(b.tableName) } if nil != o.Model { @@ -246,3 +258,43 @@ func (b *BaseDao[DatabaseDataType]) setTxCondition(inputTx *gorm.DB, optionFuncL } return tx } + +// TableName 获取数据表名 +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) TableName() string { + val := reflect.ValueOf(*new(DatabaseDataType)).MethodByName("TableName").Call(nil)[0] + return val.Interface().(string) +} + +// ColumnComment 表字段注释 +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) ColumnComment() map[string]string { + if len(b.columnComment) > 0 { + return b.columnComment + } + val := reflect.ValueOf(new(DatabaseDataType)).MethodByName("ColumnComment").Call(nil)[0] + b.columnComment = val.Interface().(map[string]string) + return b.columnComment +} + +// Columns 表字段枚举 +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) Columns() DatabaseTableColumns { + if b.isSetColumns { + return b.columns + } + b.columns = reflect.ValueOf(new(DatabaseDataType)).MethodByName("Columns").Call(nil)[0].Interface().(DatabaseTableColumns) + b.isSetColumns = true + return b.columns +} + +// DetailForAny 查询任意表数据详情 +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) DetailForAny(tx *gorm.DB, tableName string, result any, optionList ...define.SetOption) error { + optionList = append(optionList, WithTable(tableName)) + tx = b.setTxCondition(tx, optionList...) + return tx.First(result).Error +} + +// ListForAny 查询任意表数据列表 +func (b *BaseDao[DatabaseDataType, DatabaseTableColumns]) ListForAny(tx *gorm.DB, tableName string, data any, optionList ...define.SetOption) error { + optionList = append(optionList, WithTable(tableName)) + tx = b.setTxCondition(tx, optionList...) + return tx.Find(data).Error +}