tag.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package sql_mapping
  2. import (
  3. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
  4. "git.sxidc.com/go-tools/utils/reflectutils"
  5. "git.sxidc.com/go-tools/utils/strutils"
  6. "git.sxidc.com/go-tools/utils/template"
  7. "github.com/iancoleman/strcase"
  8. "github.com/pkg/errors"
  9. "reflect"
  10. "strings"
  11. )
  12. const (
  13. defaultKeyColumnName = "id"
  14. defaultJoinWith = "::"
  15. tagPartSeparator = ";"
  16. tagPartKeyValueSeparator = ":"
  17. )
  18. const (
  19. tagKey = "sqlmapping"
  20. tagPartIgnore = "-"
  21. tagPartColumn = "column"
  22. tagPartKey = "key"
  23. tagPartNotUpdate = "notUpdate"
  24. tagPartUpdateClear = "updateClear"
  25. tagPartAes = "aes"
  26. tagPartJoinWith = "joinWith"
  27. tagPartTrim = "trim"
  28. tagPartTrimPrefix = "trimPrefix"
  29. tagPartTrimSuffix = "trimSuffix"
  30. )
  31. type Tag struct {
  32. Name string
  33. IsKey bool
  34. CanUpdate bool
  35. CanUpdateClear bool
  36. JoinWith string
  37. AESKey string
  38. Trim string
  39. TrimPrefix string
  40. TrimSuffix string
  41. }
  42. func parseTag(entityElemValue reflect.Value, onParsedFieldTagFunc OnParsedFieldTagFunc) error {
  43. for i := 0; i < entityElemValue.NumField(); i++ {
  44. entityField := entityElemValue.Type().Field(i)
  45. entityFieldValue := entityElemValue.Field(i)
  46. // 无效值,不进行映射
  47. if !entityFieldValue.IsValid() {
  48. continue
  49. }
  50. if entityFieldValue.Kind() == reflect.Pointer && entityFieldValue.IsNil() {
  51. if !entityFieldValue.CanSet() {
  52. return errors.New("无法设置值,请检查是否传递的是非指针结构变量且字段为nil")
  53. }
  54. entityFieldValue.Set(reflect.New(entityField.Type.Elem()))
  55. }
  56. entityFieldElemValue := reflectutils.PointerValueElem(entityFieldValue)
  57. tagStr := entityField.Tag.Get(tagKey)
  58. tag, err := parseFieldTag(entityField, tagStr)
  59. if err != nil {
  60. return err
  61. }
  62. if tag == nil {
  63. continue
  64. }
  65. // 结构类型的字段,解析结构内部
  66. if entityFieldElemValue.Kind() == reflect.Struct &&
  67. !reflectutils.IsValueTime(entityFieldElemValue) {
  68. err := parseTag(entityFieldElemValue, onParsedFieldTagFunc)
  69. if err != nil {
  70. return err
  71. }
  72. continue
  73. }
  74. err = onParsedFieldTagFunc(entityField.Name, entityFieldElemValue, tag)
  75. if err != nil {
  76. return err
  77. }
  78. }
  79. return nil
  80. }
  81. func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
  82. if tagStr == tagPartIgnore {
  83. return nil, nil
  84. }
  85. tag := &Tag{
  86. Name: strcase.ToSnake(template.Id(field.Name)),
  87. IsKey: false,
  88. CanUpdate: true,
  89. CanUpdateClear: false,
  90. JoinWith: defaultJoinWith,
  91. AESKey: "",
  92. Trim: "",
  93. TrimPrefix: "",
  94. TrimSuffix: "",
  95. }
  96. if tag.Name == defaultKeyColumnName {
  97. tag.IsKey = true
  98. tag.CanUpdate = false
  99. }
  100. if strutils.IsStringEmpty(tagStr) {
  101. return tag, nil
  102. }
  103. tagParts := strings.Split(tagStr, tagPartSeparator)
  104. if tagParts != nil || len(tagParts) != 0 {
  105. for _, tagPart := range tagParts {
  106. tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
  107. if tagPartKeyValue != nil && len(tagPartKeyValue) == 2 && strutils.IsStringNotEmpty(tagPartKeyValue[1]) {
  108. tagPartKeyValue[1] = strings.Trim(tagPartKeyValue[1], "'")
  109. }
  110. if strutils.IsStringEmpty(tagPartKeyValue[0]) {
  111. continue
  112. }
  113. switch tagPartKeyValue[0] {
  114. case tagPartColumn:
  115. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  116. return nil, errors.New("column没有赋值列名")
  117. }
  118. tag.Name = tagPartKeyValue[1]
  119. case tagPartKey:
  120. tag.IsKey = true
  121. tag.CanUpdate = false
  122. case tagPartNotUpdate:
  123. tag.CanUpdate = false
  124. tag.CanUpdateClear = false
  125. case tagPartUpdateClear:
  126. if !tag.CanUpdate {
  127. tag.CanUpdateClear = false
  128. } else {
  129. tag.CanUpdateClear = true
  130. }
  131. case tagPartAes:
  132. if len(tagPartKeyValue[1]) != 32 {
  133. return nil, errors.New("AES密钥长度应该为32个字节")
  134. }
  135. tag.AESKey = tagPartKeyValue[1]
  136. case tagPartJoinWith:
  137. if strutils.IsStringEmpty(tagPartKeyValue[1]) {
  138. return nil, errors.New(tagPartJoinWith + "没有赋值分隔符")
  139. }
  140. tag.JoinWith = tagPartKeyValue[1]
  141. case tagPartTrim:
  142. tag.Trim = tagPartKeyValue[1]
  143. case tagPartTrimPrefix:
  144. tag.TrimPrefix = tagPartKeyValue[1]
  145. case tagPartTrimSuffix:
  146. tag.TrimSuffix = tagPartKeyValue[1]
  147. default:
  148. err := errors.New(tagKey + "不支持的tag: " + tagPartKeyValue[0])
  149. logger.GetInstance().Error(err)
  150. continue
  151. }
  152. }
  153. }
  154. return tag, nil
  155. }