| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- package tag
- import (
- "errors"
- "git.sxidc.com/go-tools/utils/reflectutils"
- "git.sxidc.com/go-tools/utils/strutils"
- "git.sxidc.com/service-supports/fserr"
- "github.com/iancoleman/strcase"
- "reflect"
- "strings"
- )
- type OnSqlMappingParsedFieldTagFunc func(fieldName string, entityFieldElemValue reflect.Value, sqlMapping *SqlMappingTag) error
- func UseSqlMappingTag(e any, onParsedFieldTagFunc OnSqlMappingParsedFieldTagFunc) error {
- if e == nil {
- return nil
- }
- entityValue := reflect.ValueOf(e)
- // 类型校验
- if !reflectutils.IsValueStructOrStructPointer(entityValue) {
- return fserr.New("参数不是结构或结构指针")
- }
- entityElemValue := reflectutils.PointerValueElem(entityValue)
- err := parseEntitySqlMappingTag(entityElemValue, onParsedFieldTagFunc)
- if err != nil {
- return err
- }
- return nil
- }
- func parseEntitySqlMappingTag(entityElemValue reflect.Value, onParsedFieldTagFunc OnSqlMappingParsedFieldTagFunc) error {
- for i := 0; i < entityElemValue.NumField(); i++ {
- entityField := entityElemValue.Type().Field(i)
- entityFieldValue := entityElemValue.Field(i)
- // 无效值,不进行映射
- if !entityFieldValue.IsValid() {
- continue
- }
- if entityFieldValue.Kind() == reflect.Pointer && entityFieldValue.IsNil() {
- entityFieldValue.Set(reflect.New(entityField.Type.Elem()))
- }
- entityFieldElemValue := reflectutils.PointerValueElem(entityFieldValue)
- tagStr := entityField.Tag.Get(sqlMappingTagKey)
- sqlMapping, err := parseSqlMappingTag(entityField, tagStr)
- if err != nil {
- return err
- }
- if sqlMapping == nil {
- continue
- }
- // 结构类型的字段,解析结构内部
- if entityFieldElemValue.Kind() == reflect.Struct &&
- !reflectutils.IsValueTime(entityFieldElemValue) {
- err := parseEntitySqlMappingTag(entityFieldElemValue, onParsedFieldTagFunc)
- if err != nil {
- return err
- }
- continue
- }
- err = onParsedFieldTagFunc(entityField.Name, entityFieldElemValue, sqlMapping)
- if err != nil {
- return err
- }
- }
- return nil
- }
- const (
- sqlMappingDefaultKeyColumnName = "id"
- sqlMappingDefaultJoinWith = "::"
- sqlMappingTagPartSeparator = ";"
- sqlMappingTagPartKeyValueSeparator = ":"
- )
- const (
- sqlMappingTagKey = "sqlmapping"
- sqlMappingIgnore = "-"
- sqlMappingColumn = "column"
- sqlMappingKey = "key"
- sqlMappingNotUpdate = "notUpdate"
- sqlMappingUpdateClear = "updateClear"
- sqlMappingAes = "aes"
- sqlMappingJoinWith = "joinWith"
- sqlMappingTrim = "trim"
- sqlMappingTrimPrefix = "trimPrefix"
- sqlMappingTrimSuffix = "trimSuffix"
- )
- type SqlMappingTag struct {
- Name string
- IsKey bool
- CanUpdate bool
- CanUpdateClear bool
- AESKey string
- JoinWith string
- Trim string
- TrimPrefix string
- TrimSuffix string
- }
- func parseSqlMappingTag(field reflect.StructField, tagStr string) (*SqlMappingTag, error) {
- if tagStr == sqlMappingIgnore {
- return nil, nil
- }
- sqlMappingTag := &SqlMappingTag{
- Name: strcase.ToSnake(field.Name),
- IsKey: false,
- CanUpdate: true,
- CanUpdateClear: false,
- AESKey: "",
- JoinWith: sqlMappingDefaultJoinWith,
- Trim: "",
- TrimPrefix: "",
- TrimSuffix: "",
- }
- if sqlMappingTag.Name == sqlMappingDefaultKeyColumnName {
- sqlMappingTag.IsKey = true
- sqlMappingTag.CanUpdate = false
- }
- if strutils.IsStringEmpty(tagStr) {
- return sqlMappingTag, nil
- }
- sqlMappingParts := strings.Split(tagStr, sqlMappingTagPartSeparator)
- if sqlMappingParts != nil || len(sqlMappingParts) != 0 {
- for _, sqlMappingPart := range sqlMappingParts {
- sqlMappingPartKeyValue := strings.SplitN(strings.TrimSpace(sqlMappingPart), sqlMappingTagPartKeyValueSeparator, 2)
- if sqlMappingPartKeyValue != nil && len(sqlMappingPartKeyValue) == 2 && strutils.IsStringNotEmpty(sqlMappingPartKeyValue[1]) {
- sqlMappingPartKeyValue[1] = strings.Trim(sqlMappingPartKeyValue[1], "'")
- }
- switch sqlMappingPartKeyValue[0] {
- case sqlMappingColumn:
- if strutils.IsStringEmpty(sqlMappingPartKeyValue[1]) {
- return nil, errors.New("column没有赋值列名")
- }
- sqlMappingTag.Name = sqlMappingPartKeyValue[1]
- case sqlMappingKey:
- sqlMappingTag.IsKey = true
- sqlMappingTag.CanUpdate = false
- case sqlMappingNotUpdate:
- sqlMappingTag.CanUpdate = false
- sqlMappingTag.CanUpdateClear = false
- case sqlMappingUpdateClear:
- if !sqlMappingTag.CanUpdate {
- sqlMappingTag.CanUpdateClear = false
- } else {
- sqlMappingTag.CanUpdateClear = true
- }
- case sqlMappingAes:
- if len(sqlMappingPartKeyValue[1]) != 32 {
- return nil, errors.New("AES密钥长度应该为32个字节")
- }
- sqlMappingTag.AESKey = sqlMappingPartKeyValue[1]
- case sqlMappingJoinWith:
- if strutils.IsStringEmpty(sqlMappingPartKeyValue[1]) {
- return nil, errors.New(sqlMappingJoinWith + "没有赋值分隔符")
- }
- sqlMappingTag.JoinWith = sqlMappingPartKeyValue[1]
- case sqlMappingTrim:
- sqlMappingTag.Trim = sqlMappingPartKeyValue[1]
- case sqlMappingTrimPrefix:
- sqlMappingTag.TrimPrefix = sqlMappingPartKeyValue[1]
- case sqlMappingTrimSuffix:
- sqlMappingTag.TrimSuffix = sqlMappingPartKeyValue[1]
- default:
- continue
- }
- }
- }
- return sqlMappingTag, nil
- }
|