golang gorm通过泛型实现通用单表增删改

golang gorm通过泛型实现通用单表增删改

无废话,直接上代码

想实现通用,首先得实现查询的通用,可以用传递map实现

func Where(where map[string]interface{}) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		dbTmp := db
		for ko, value := range where {
			koSlice := strings.Split(ko, "#")
			var key, op string
			if len(koSlice) == 1 {
				key = ko
				if php2go.InArray(key, []string{"select", "order", "offset", "limit"}) {
					op = ko
				} else {
					op = "eq"
				}
			} else {
				key = koSlice[0]
				op = koSlice[1]
			}
			switch op {
			case "eq":
				dbTmp.Where(key+" = ?", value)
			case "neq":
				dbTmp.Where(key+" != ?", value)
			case "gt":
				dbTmp.Where(key+" > ?", value)
			case "gte":
				dbTmp.Where(key+" >= ?", value)
			case "lt":
				dbTmp.Where(key+" < ?", value)
			case "lte":
				dbTmp.Where(key+" <= ?", value)
			case "like":
				dbTmp.Where(key+" like ?", "%"+value.(string)+"%")
			case "in":
				dbTmp.Where(key+" in ?", value)
			case "notin":
				dbTmp.Where(key+" not in ?", value)
			case "between":
				dbTmp.Where(key+" between ? and ?", value.([]int)[0], value.([]int)[1])
			case "betweens":
				dbTmp.Where(key+" between ? and ?", value.([]string)[0], value.([]string)[1])
			case "select":
				dbTmp.Select(value.(string))
			case "order":
				dbTmp.Order(value.(string))
			case "offset":
				dbTmp.Offset(value.(int))
			case "limit":
				dbTmp.Limit(value.(int))
			}
		}
		return dbTmp
	}
}

调用方式

examleWhere := map[string]interface{}{
				"name#like":           data.ToUserName,
				"id":        		   data.UserID,
				"create_time#between": []int{17000000, 18000000},
				"grade#in":            []int{3,4},
				"order":               "id desc",
			}
Gorm().Table("xxx").Scopes(Where(examleWhere)).xxx

打印 sql:
select * from xxx where name like "%xx%" and id = xxx and create_time between 17xxx and 18xxx and grade in (3,4) order by id desc

通用查询

type FieldType interface {
	uint | uint8 | uint16 | uint32 | uint64 | int | int8 | int16 | int32 | int64 | float32 | float64 | string
}
func Get[T any](where map[string]interface{}, field ...string) (ret T, err error) {
	db := sys.Gorm().Scopes(Where(where)).Where("delete_time = 0")
	if len(field) > 0 {
		db.Select(field)
	}
	err = db.Find(&ret).Error
	return
}

func GetVal[T FieldType](tableName string, where map[string]interface{}, field string, includeDel ...bool) (ret T, err error) {
	db := sys.Gorm().Table(tableName).Scopes(Where(where)).Select(field)
	if len(includeDel) > 0 && includeDel[0] == true {
		db.Unscoped()
	} else {
		db.Where("delete_time = 0")
	}
	err = db.Find(&ret).Error
	return
}

func Gets[T any](where map[string]interface{}, field ...string) (ret []T, err error) {
	db := sys.Gorm().Scopes(Where(where)).Where("delete_time = 0")
	if len(field) > 0 {
		db.Select(field)
	}
	err = db.Find(&ret).Error
	return
}

func GetSlice[T FieldType](tableName string, where map[string]interface{}, field string, includeDel ...bool) (ret []T, err error) {
	ret = make([]T, 0)
	db := sys.Gorm().Table(tableName).Scopes(Where(where)).Select(field)
	if len(includeDel) > 0 && includeDel[0] == true {
		db.Unscoped()
	} else {
		db.Where("delete_time = 0")
	}
	err = db.Find(&ret).Error
	return
}

func Update[T any](where map[string]interface{}, update T) (err error) {
	db := sys.Gorm()
	err = db.Scopes(Where(where)).Updates(update).Error
	return
}

func UpdateByMap(table string, where, update map[string]interface{}) (err error) {
	db := sys.Gorm().Table(table)
	err = db.Scopes(Where(where)).Updates(update).Error
	return
}

func UpdateByMapTx(tx *gorm.DB, table string, where, update map[string]interface{}) (err error) {
	db := tx.Table(table)
	err = db.Scopes(Where(where)).Updates(update).Error
	return
}

// Create
// doUpdate: on duplicate key update : all, []string{}...
func Create[T any](data *[]T, doUpdate ...string) (err error) {
	var db *gorm.DB
	if len(doUpdate) > 0 {
		if doUpdate[0] == "all" {
			db = sys.Gorm().Clauses(clause.OnConflict{
				UpdateAll: true,
			}).Scopes()
		} else {
			db = sys.Gorm().Clauses(clause.OnConflict{
				DoUpdates: clause.AssignmentColumns(doUpdate),
			}).Scopes()
		}
	} else {
		db = sys.Gorm().Scopes()
	}
	err = db.Create(&data).Error
	return
}

func CreateTx[T any](tx *gorm.DB, data *T, doUpdate ...string) (err error) {
	if len(doUpdate) > 0 {
		if doUpdate[0] == "all" {
			tx.Clauses(clause.OnConflict{
				UpdateAll: true,
			}).Scopes()
		} else {
			tx.Clauses(clause.OnConflict{
				DoUpdates: clause.AssignmentColumns(doUpdate),
			}).Scopes()
		}
	}
	err = tx.Create(&data).Error
	return
}

func CreatesTx[T any](tx *gorm.DB, data *[]T, doUpdate ...string) (err error) {
	if len(doUpdate) > 0 {
		if doUpdate[0] == "all" {
			tx.Clauses(clause.OnConflict{
				UpdateAll: true,
			}).Scopes()
		} else {
			tx.Clauses(clause.OnConflict{
				DoUpdates: clause.AssignmentColumns(doUpdate),
			}).Scopes()
		}
	}
	err = tx.Create(&data).Error
	return
}

给出调用方式案例

model.Get[model.WwStaff](map[string]interface{}{"corp_id": req.CorpId, "userid": req.StaffUserid})

model.GetVal[int]("table_name", map[string]interface{}{
			"corp_id":     corpId,
			"dept_id":     deptId,
			"delete_time": 0,
		}, "parentid")
		
model.GetSlice[int64]("table_name",map[string]interface{}{"staff_id": req.Id}, "id")

// insert ...
model.Create(&tableModel)
// insert ... ON DUPLICATE KEY UPDATE id = VALUES(id) ......
model.Create(&tableModel, "id", "update_time")

model.UpdateByMap("table_name",
			map[string]interface{}{"id#in": roomUnionIds},
			map[string]interface{}{"upload": 2})
			
model.UpdateByMapTx(tx, "table_name",
			map[string]interface{}{"id#in": roomUnionIds},
			map[string]interface{}{"upload": 2})

可以依照代码,写出其它灵活的使用方式
结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Golang GORM进行MySQL递归查询单表的示例代码: ```go package main import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type Category struct { ID int Name string ParentID int Children []Category `gorm:"foreignkey:ParentID"` } func main() { db, err := gorm.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local") if err != nil { panic(err) } defer db.Close() var categories []Category db.Where("parent_id = ?", 0).Preload("Children").Find(&categories) for _, category := range categories { fmt.Println(category.Name) for _, child := range category.Children { fmt.Println(" ", child.Name) } } } ``` 在这个示例中,我们定义了一个Category结构体,其中包含ID、Name、ParentID和Children字段。Children字段是一个Category类型的切片,用于存储子类别。在结构体中,我们使用了GORM的foreignkey标记来指定ParentID字段是外键,Children字段是通过ParentID字段与Category表关联的。 在main函数中,我们首先使用GORM的Open函数打开MySQL数据库连接。然后,我们定义了一个categories切片,用于存储查询结果。我们使用GORM的Where函数指定ParentID为0,即查询所有顶级类别。然后,我们使用GORM的Preload函数预加载Children字段,以便在查询结果中包含子类别。最后,我们使用GORM的Find函数执行查询,并将结果存储在categories切片中。 最后,我们遍历categories切片,并打印每个类别及其子类别的名称。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值