package dao import ( "fmt" putils "git.rosy.net.cn/jx-print/utils" "github.com/jmoiron/sqlx" "reflect" "strings" "time" ) func Insert(db *sqlx.DB, obj interface{}) (err error) { var ( value = reflect.ValueOf(obj) stype = reflect.TypeOf(obj) sql, values = strings.Builder{}, strings.Builder{} sqlParams = []interface{}{} direct reflect.Value ) if stype.Kind() != reflect.Struct { direct = reflect.Indirect(value) stype = stype.Elem() } else { direct = value } sname := stype.Name() sql.WriteString("INSERT INTO ") for i := 0; i < stype.NumField()-1; i++ { if stype.Field(i).Type.String() == "*time.Time" { if direct.Field(i).Interface().(*time.Time) != nil { values.WriteString(stype.Field(i).Tag.Get("json") + ",") sqlParams = append(sqlParams, direct.Field(i).Interface()) } } else { if !direct.Field(i).IsZero() { values.WriteString(stype.Field(i).Tag.Get("json") + ",") sqlParams = append(sqlParams, direct.Field(i).Interface()) } } } sql.WriteString(putils.UnMarshalHr(sname) + "(") sql.WriteString(values.String()[:len(values.String())-1]) sql.WriteString(") VALUES(") for i := 0; i < len(strings.Split(values.String(), ","))-1; i++ { if i != 0 { sql.WriteString(",") } sql.WriteString("?") } sql.WriteString(")") _, err = db.DB.Exec(sql.String(), sqlParams...) return err } func Update(db *sqlx.DB, obj interface{}, fields ...string) (err error) { var ( value = reflect.ValueOf(obj) stype = reflect.TypeOf(obj) sql = strings.Builder{} sqlParams = []interface{}{} direct reflect.Value fieldsMap = make(map[string]string) ) if stype.Kind() != reflect.Struct { direct = reflect.Indirect(value) stype = stype.Elem() } else { direct = value } sname := stype.Name() sql.WriteString("UPDATE ") sql.WriteString(putils.UnMarshalHr(sname) + " SET ") fieldsStr := []string{} for _, v := range fields { fieldsStr = append(fieldsStr, v+"=?") fieldsMap[v] = v } sql.WriteString(strings.Join(fieldsStr, ",")) sql.WriteString(" WHERE id = ?") for i := 0; i < stype.NumField()-1; i++ { if fieldsMap[stype.Field(i).Tag.Get("json")] != "" { if stype.Field(i).Type.String() == "*time.Time" { if direct.Field(i).Interface().(*time.Time) != nil { sqlParams = append(sqlParams, direct.Field(i).Interface()) } } else { if !direct.Field(i).IsZero() { sqlParams = append(sqlParams, direct.Field(i).Interface()) } } } } if direct.Field(0).Int() == 0 { return err } else { sqlParams = append(sqlParams, direct.Field(0).Int()) } fmt.Println(sql) fmt.Println(sqlParams) _, err = db.DB.Exec(sql.String(), sqlParams...) return err } //更新两个结构体中不同的字段 //obj是作为参数,obj2是原本的要更新的 func UpdateDiff(db *sqlx.DB, obj interface{}, obj2 interface{}) (err error) { var ( value = reflect.ValueOf(obj) stype = reflect.TypeOf(obj) value2 = reflect.ValueOf(obj2) stype2 = reflect.TypeOf(obj2) sql = strings.Builder{} sqlParams = []interface{}{} fieldMap1 = make(map[string]interface{}) fieldMap2 = make(map[string]interface{}) fields = make(map[string]interface{}) ) if stype.Kind() != reflect.Struct { stype = stype.Elem() value = reflect.Indirect(value) } if stype2.Kind() != reflect.Struct { stype2 = stype2.Elem() value2 = reflect.Indirect(value2) } sname := stype.Name() sname2 := stype2.Name() if sname != sname2 { return fmt.Errorf("请传入两个类型相同的结构体!") } for i := 5; i < stype.NumField()-1; i++ { if !value.Field(i).IsZero() { fieldMap1[stype.Field(i).Tag.Get("json")] = value.Field(i).Interface() } } for i := 5; i < stype2.NumField()-1; i++ { if !value2.Field(i).IsZero() { fieldMap2[stype2.Field(i).Tag.Get("json")] = value2.Field(i).Interface() } } for k, v := range fieldMap1 { if fieldMap2[k] != nil { if fieldMap2[k] != v { fields[k] = v } } } sql.WriteString("UPDATE ") sql.WriteString(putils.UnMarshalHr(sname) + " SET ") if len(fields) == 0 { return err } fieldsStr := []string{} for k, v := range fields { fieldsStr = append(fieldsStr, k+"=?") sqlParams = append(sqlParams, v) } sql.WriteString(strings.Join(fieldsStr, ",")) sql.WriteString(" WHERE id = ?") if value2.Field(0).Int() == 0 { return err } else { sqlParams = append(sqlParams, value2.Field(0).Int()) } _, err = db.DB.Exec(sql.String(), sqlParams...) return err }