golang gorm implements general single table addition, deletion and modification through generics
No nonsense, just jump into the code
If you want to achieve universality, you must first implement universal query, which can be achieved by passing 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 } }
Calling method
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 print 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
General query
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( & amp;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 & amp; & amp; includeDel[0] == true { db.Unscoped() } else { db.Where("delete_time = 0") } err = db.Find( & amp;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( & amp;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 & amp; & amp; includeDel[0] == true { db.Unscoped() } else { db.Where("delete_time = 0") } err = db.Find( & amp;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 }
Give examples of calling methods
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") \t\t 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( & amp;tableModel, "id", "update_time") model.UpdateByMap("table_name", map[string]interface{}{"id#in": roomUnionIds}, map[string]interface{}{"upload": 2}) \t\t\t model.UpdateByMapTx(tx, "table_name", map[string]interface{}{"id#in": roomUnionIds}, map[string]interface{}{"upload": 2})
You can write other flexible usage methods according to the code
Finish