1. 查询结果反射结构体

本文讲解的实例是从mysql查询过来的数据如何反射到结构体字段,具体实现方法如下代码;

代码目录:

1129

-common

—common.go //是封装的代码

-main.go //是测试代码

代码的封装:

  1. package common
  2. import (
  3. "errors"
  4. "reflect"
  5. "strconv"
  6. "time"
  7. )
  8. //根据结构体中sql标签映射数据到结构体中并且转换类型
  9. func DataToStructByTagSql(data map[string]string, obj interface{}) {
  10. objValue := reflect.ValueOf(obj).Elem()
  11. for i := 0; i < objValue.NumField(); i++ {
  12. //获取sql对应的值
  13. value := data[objValue.Type().Field(i).Tag.Get("sql")]
  14. //获取对应字段的名称
  15. name := objValue.Type().Field(i).Name
  16. //获取对应字段类型
  17. structFieldType := objValue.Field(i).Type()
  18. //获取变量类型,也可以直接写"string类型"
  19. val := reflect.ValueOf(value)
  20. var err error
  21. if structFieldType != val.Type() {
  22. //类型转换
  23. val, err = TypeConversion(value, structFieldType.Name()) //类型转换
  24. if err != nil {
  25. }
  26. }
  27. //设置类型值
  28. objValue.FieldByName(name).Set(val)
  29. }
  30. }
  31. //类型转换
  32. func TypeConversion(value string, ntype string) (reflect.Value, error) {
  33. if ntype == "string" {
  34. return reflect.ValueOf(value), nil
  35. } else if ntype == "time.Time" {
  36. t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  37. return reflect.ValueOf(t), err
  38. } else if ntype == "Time" {
  39. t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  40. return reflect.ValueOf(t), err
  41. } else if ntype == "int" {
  42. i, err := strconv.Atoi(value)
  43. return reflect.ValueOf(i), err
  44. } else if ntype == "int8" {
  45. i, err := strconv.ParseInt(value, 10, 64)
  46. return reflect.ValueOf(int8(i)), err
  47. } else if ntype == "int32" {
  48. i, err := strconv.ParseInt(value, 10, 64)
  49. return reflect.ValueOf(int64(i)), err
  50. } else if ntype == "int64" {
  51. i, err := strconv.ParseInt(value, 10, 64)
  52. return reflect.ValueOf(i), err
  53. } else if ntype == "float32" {
  54. i, err := strconv.ParseFloat(value, 64)
  55. return reflect.ValueOf(float32(i)), err
  56. } else if ntype == "float64" {
  57. i, err := strconv.ParseFloat(value, 64)
  58. return reflect.ValueOf(i), err
  59. }
  60. //else if .......增加其他一些类型的转换
  61. return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
  62. }

代码的测试:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/student/1129/common"
  5. )
  6. //Product Product定义一个结构体
  7. type Product struct {
  8. ID int64 `json:"id" sql:"id"`
  9. ProductClass string `json:"ProductClass" sql:"ProductClass"`
  10. ProductName string `json:"ProductName" sql:"productName"`
  11. ProductNum int64 `json:"ProductNum" sql:"productNum"`
  12. ProductImage string `json:"ProductImage" sql:"productImage"`
  13. ProductURL string `json:"ProductUrl" sql:"productUrl" `
  14. }
  15. func main() {
  16. //这块是模拟mysql获取单条的数据反射到结构体
  17. data := map[string]string{"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"}
  18. productResult := &Product{}
  19. common.DataToStructByTagSql(data, productResult)
  20. fmt.Println(*productResult)
  21. //这块是模拟mysql获取所有的数据反射到结构体
  22. Alldata := []map[string]string{
  23. {"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
  24. {"id": "2", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
  25. }
  26. var productArray []*Product
  27. for _, v := range Alldata {
  28. Allproduct := &Product{}
  29. common.DataToStructByTagSql(v, Allproduct)
  30. productArray = append(productArray, Allproduct)
  31. }
  32. for _, vv := range productArray {
  33. fmt.Println(vv)
  34. }
  35. }