//根据传入的struct中定义的字段名自动小写首字母,查询得到的值自动插入struct中.当然也可以用tag查询,但是需要首先把tag取出来,然后做一个map把tag值和对应的field存储起来.
func SelectOne(i interface{}, query string, a ...interface{}) {
rows, err := db.Query(query, a...)
if nil != err {
log.Println(err)
return
}
cols, err := rows.Columns()
if nil != err {
log.Println(err)
return
}
is := make([]interface{}, len(cols))
val := reflect.ValueOf(i)
for i, v := range cols {
v = strings.ToUpper(v[0:1]) + v[1:]
//这句话是关键所在
is[i] = val.Elem().FieldByName(v).Addr().Interface()
}
if rows.Next() {
err = rows.Scan(is...)
if nil != err {
log.Println(err)
return
}
}
}
//根据传入的struct中定义的mysql tag自动生成响应的sql语句.
func InsertSql(i interface{}) (string, error) {
tp := reflect.TypeOf(i)
if tp.Kind() != reflect.Ptr && tp.Kind() != reflect.Struct {
log.Println("non-ptr or not-struct")
return "", errors.New("non-ptr or not-struct")
}
length := tp.Elem().NumField()
fields := []reflect.StructField{}
for i := 0; i < length; i++ {
field := tp.Elem().Field(i)
fields = append(fields, field)
}
val := reflect.ValueOf(i)
names := []string{}
values := []string{}
for _, field := range fields {
n := field.Tag.Get("mysql")
names = append(names, n)
switch val.Elem().FieldByName(field.Name).Type().Kind() {
case reflect.String:
v := val.Elem().FieldByName(field.Name).String()
values = append(values, "'"+v+"'")
case reflect.Uint, reflect.Uint8:
v := val.Elem().FieldByName(field.Name).Uint()
values = append(values, fmt.Sprintf("%d", v))
case reflect.Int:
v := val.Elem().FieldByName(field.Name).Int()
values = append(values, fmt.Sprintf("%d", v))
}
}
insertSQL := "INSERT INTO " + strings.ToLower(tp.Elem().Name()) + "("
vals := strings.Join(values, ",")
ns := strings.Join(names, ",")
insertSQL += ns + ") " + "VALUES(" + vals + ")"
log.Println(insertSQL)
return insertSQL, nil
}
有疑问加站长微信联系(非本文作者)