Browse Source

完成sqlresult tag

yjp 1 year ago
parent
commit
17ac123b9d
8 changed files with 348 additions and 84 deletions
  1. 1 2
      go.mod
  2. 2 4
      go.sum
  3. 172 0
      sql/parse_table_row.go
  4. 10 54
      sql/sql.go
  5. 5 5
      sql/sql_mapping.go
  6. 138 0
      sql/sql_result.go
  7. 1 1
      sql/sql_tpl/value.go
  8. 19 18
      test/sdk_test.go

+ 1 - 2
go.mod

@@ -4,11 +4,10 @@ go 1.22.0
 
 require (
 	git.sxidc.com/go-tools/api_binding v1.3.23
-	git.sxidc.com/go-tools/utils v1.5.1
+	git.sxidc.com/go-tools/utils v1.5.5
 	github.com/fatih/structs v1.1.0
 	github.com/golang/protobuf v1.5.4
 	github.com/iancoleman/strcase v0.3.0
-	github.com/mitchellh/mapstructure v1.5.0
 	github.com/mwitkow/go-proto-validators v0.3.2
 	google.golang.org/grpc v1.63.2
 	google.golang.org/protobuf v1.33.0

+ 2 - 4
go.sum

@@ -1,7 +1,7 @@
 git.sxidc.com/go-tools/api_binding v1.3.23 h1:vgCdYq09aiw7Vs9JeOR0OZLOjezbHugQ/3ABeakvD4g=
 git.sxidc.com/go-tools/api_binding v1.3.23/go.mod h1:SmUnRrMtODonLzWmWCGQN9uAB2TjH8g5yEKFnp4rEgU=
-git.sxidc.com/go-tools/utils v1.5.1 h1:ZieAG9u9jRSPS4mndefmJYmSxN41IWZhl6Y/VeMgFw4=
-git.sxidc.com/go-tools/utils v1.5.1/go.mod h1:d8cjo9Wz5Vm/79pg3H43woycgZ74brPO0RysPDOBh2k=
+git.sxidc.com/go-tools/utils v1.5.5 h1:6WubGr/jxS16JJJLPQPvoO+n7nvW/u0ZOeoFCTckAdA=
+git.sxidc.com/go-tools/utils v1.5.5/go.mod h1:d8cjo9Wz5Vm/79pg3H43woycgZ74brPO0RysPDOBh2k=
 git.sxidc.com/service-supports/fserr v0.3.2 h1:5/FCr8o2jd1kNsp5tH/ADjB9fr091JZXMMZ15ZvNZzs=
 git.sxidc.com/service-supports/fserr v0.3.2/go.mod h1:W54RoA71mfex+zARuH/iMnQPMnBXQ23qXXOkwUh2sVQ=
 git.sxidc.com/service-supports/fslog v0.5.9 h1:q2XIK2o/fk/qmByy4x5kKLC+k7kolT5LrXHcWRSffXQ=
@@ -76,8 +76,6 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
 github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
 github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

+ 172 - 0
sql/parse_table_row.go

@@ -0,0 +1,172 @@
+package sql
+
+import (
+	"errors"
+	"fmt"
+	"git.sxidc.com/go-tools/utils/encoding"
+	"git.sxidc.com/go-tools/utils/reflectutils"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"reflect"
+	"strings"
+	"time"
+)
+
+const (
+	sqlResultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00"
+	sqlResultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00"
+	sqlResultTimeSecFormat   = "2006-01-02T15:04:05+08:00"
+)
+
+func parseSqlTableRowTimeStr(timeStr string) (time.Time, error) {
+	var layout string
+
+	if strings.HasSuffix(timeStr, ".000000+08:00") {
+		layout = sqlResultTimeMicroFormat
+	} else if strings.HasSuffix(timeStr, ".000+08:00") {
+		layout = sqlResultTimeMilliFormat
+	} else {
+		layout = sqlResultTimeSecFormat
+	}
+
+	return time.ParseInLocation(layout, timeStr, time.Local)
+}
+
+func ParseSqlTableRow(input any, output any) error {
+	if input == nil || output == nil {
+		return nil
+	}
+
+	outputType := reflect.TypeOf(output)
+	if outputType.Kind() != reflect.Ptr {
+		return errors.New("输出实体应该为结构的slice或者是结构的指针")
+	}
+
+	if outputType.Kind() == reflect.Ptr {
+		outputType = outputType.Elem()
+	}
+
+	if outputType.Kind() != reflect.Slice && outputType.Kind() != reflect.Struct {
+		return errors.New("输出实体应该为结构的slice或者是结构的指针")
+	}
+
+	outputElemType := outputType
+	if outputType.Kind() == reflect.Slice {
+		outputElemType = outputType.Elem()
+	}
+
+	fmt.Println(outputElemType.String())
+
+	tableRows, ok := input.([]map[string]any)
+	if !ok {
+		tableRow, ok := input.(map[string]any)
+		if !ok {
+			return errors.New("输入数据应该为[]map[string]any或[]map[string]any")
+		}
+
+		tableRows = []map[string]any{tableRow}
+	}
+
+	outputEntities := reflect.MakeSlice(reflect.SliceOf(outputElemType), 0, 0)
+
+	for _, tableRow := range tableRows {
+		outputEntityValue := reflect.New(outputElemType).Elem().Addr()
+		outputEntity := outputEntityValue.Interface()
+
+		sqlResult, err := ParseSqlResult(outputEntity)
+		if err != nil {
+			return err
+		}
+
+		for fieldName, sqlColumn := range sqlResult.ColumnMap {
+			tableRowValue, ok := tableRow[sqlColumn.Name]
+			if !ok {
+				continue
+			}
+
+			fieldValue := sqlColumn.OriginFieldValue
+			if fieldValue.Type().Kind() == reflect.Ptr {
+				if fieldValue.IsValid() {
+					fieldValue.Set(reflect.New(sqlColumn.FieldTypeElem))
+				}
+
+				fieldValue = fieldValue.Elem()
+			}
+
+			outputKind := reflectutils.GroupValueKind(fieldValue)
+
+			switch outputKind {
+			case reflect.Bool:
+				err := reflectutils.AssignBoolValue(tableRowValue, fieldValue)
+				if err != nil {
+					return err
+				}
+			case reflect.String:
+				strValue := tableRowValue.(string)
+
+				if strutils.IsStringNotEmpty(sqlColumn.ParseTime) {
+					parsedTime, err := parseSqlTableRowTimeStr(strValue)
+					if err != nil {
+						return err
+					}
+
+					tableRowValue = parsedTime.Format(sqlColumn.ParseTime)
+				} else if strutils.IsStringNotEmpty(sqlColumn.AESKey) {
+					decryptedValue, err := encoding.AESDecrypt(strValue, sqlColumn.AESKey)
+					if err != nil {
+						return err
+					}
+
+					strValue = decryptedValue
+				}
+
+				err = reflectutils.AssignStringValue(strValue, fieldValue)
+				if err != nil {
+					return err
+				}
+			case reflect.Int64:
+				err := reflectutils.AssignIntValue(tableRowValue, fieldValue)
+				if err != nil {
+					return err
+				}
+			case reflect.Uint64:
+				err := reflectutils.AssignUintValue(tableRowValue, fieldValue)
+				if err != nil {
+					return err
+				}
+			case reflect.Float64:
+				err := reflectutils.AssignFloatValue(tableRowValue, fieldValue)
+				if err != nil {
+					return err
+				}
+			case reflect.Struct:
+				if fieldValue.Type() == reflect.TypeOf(time.Time{}) {
+					parsedTime, err := parseSqlTableRowTimeStr(tableRowValue.(string))
+					if err != nil {
+						return err
+					}
+
+					fieldValue.Set(reflect.ValueOf(parsedTime))
+					continue
+				}
+
+				return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
+					fieldName, sqlColumn.Name, reflect.TypeOf(tableRowValue).String())
+			default:
+				return fmt.Errorf("字段: %s 列: %s 不支持的类型: %s",
+					fieldName, sqlColumn.Name, reflect.TypeOf(tableRowValue).String())
+			}
+		}
+
+		outputEntities = reflect.Append(outputEntities, outputEntityValue.Elem())
+	}
+
+	outputValue := reflect.Indirect(reflect.ValueOf(output))
+	if outputType.Kind() == reflect.Slice {
+		outputValue.Set(outputEntities)
+	} else {
+		fmt.Println(outputValue.Type().String())
+		outputValue.Set(outputEntities.Index(0))
+	}
+
+	return nil
+}

+ 10 - 54
sql/sql.go

@@ -5,7 +5,6 @@ import (
 	"git.sxidc.com/go-tools/utils/strutils"
 	"git.sxidc.com/service-supports/ds-sdk/sdk"
 	"git.sxidc.com/service-supports/ds-sdk/sql/sql_tpl"
-	"github.com/mitchellh/mapstructure"
 	"reflect"
 	"strings"
 	"time"
@@ -44,12 +43,12 @@ func InsertEntity[T any](executor Executor, tableName string, e T) error {
 	now := time.Now()
 
 	for fieldName, sqlColumn := range sqlMapping.ColumnMap {
-		fieldType := sqlColumn.ValueFieldType
+		fieldType := sqlColumn.FieldTypeElem
 
 		// 有值取值,没有值构造零值
 		value := reflect.Zero(fieldType).Interface()
-		if !sqlColumn.ValueFieldValue.IsZero() {
-			value = sqlColumn.ValueFieldValue.Interface()
+		if !sqlColumn.FieldValueElem.IsZero() {
+			value = sqlColumn.FieldValueElem.Interface()
 		}
 
 		// 自动添加创建时间和更新时间
@@ -113,7 +112,7 @@ func DeleteEntity[T any](executor Executor, tableName string, e T) error {
 		}
 
 		// 键字段没有赋值
-		if sqlColumn.ValueFieldValue.IsZero() {
+		if sqlColumn.FieldValueElem.IsZero() {
 			return errors.New("键字段没有传值")
 		}
 
@@ -122,7 +121,7 @@ func DeleteEntity[T any](executor Executor, tableName string, e T) error {
 			opts = append(opts, sql_tpl.WithAESKey(sqlColumn.AESKey))
 		}
 
-		conditions.Equal(sqlColumn.Name, sqlColumn.ValueFieldValue.Interface(), opts...)
+		conditions.Equal(sqlColumn.Name, sqlColumn.FieldValueElem.Interface(), opts...)
 	}
 
 	executeParamsMap, err := sql_tpl.DeleteExecuteParams{
@@ -167,22 +166,22 @@ func UpdateEntity[T any](executor Executor, tableName string, e T) error {
 	for fieldName, sqlColumn := range sqlMapping.ColumnMap {
 		if sqlColumn.IsKey {
 			// 键字段但是没有赋值
-			if sqlColumn.ValueFieldValue.IsZero() {
+			if sqlColumn.FieldValueElem.IsZero() {
 				return errors.New("键字段没有传值")
 			}
 		} else {
 			// 不是键字段
 			// 不更新的字段或者字段为空且不能清空,跳过
-			if !sqlColumn.CanUpdate || (sqlColumn.ValueFieldValue.IsZero() && !sqlColumn.CanUpdateClear) {
+			if !sqlColumn.CanUpdate || (sqlColumn.FieldValueElem.IsZero() && !sqlColumn.CanUpdateClear) {
 				continue
 			}
 		}
 
-		fieldType := sqlColumn.ValueFieldType
+		fieldType := sqlColumn.FieldTypeElem
 
 		value := reflect.Zero(fieldType).Interface()
-		if !sqlColumn.ValueFieldValue.IsZero() {
-			value = sqlColumn.ValueFieldValue.Interface()
+		if !sqlColumn.FieldValueElem.IsZero() {
+			value = sqlColumn.FieldValueElem.Interface()
 		}
 
 		if fieldName == lastUpdatedTimeFieldName &&
@@ -445,46 +444,3 @@ func ExecuteSql(executor Executor, name string, executeParams map[string]any) ([
 
 	return tableRows, nil
 }
-
-const (
-	sqlResultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00"
-	sqlResultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00"
-	sqlResultTimeSecFormat   = "2006-01-02T15:04:05+08:00"
-)
-
-func ParseSqlResults(results any, e any) error {
-	decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
-		DecodeHook: func(fromType reflect.Type, toType reflect.Type, data interface{}) (interface{}, error) {
-			if fromType.Kind() != reflect.String {
-				return data, nil
-			}
-
-			if toType != reflect.TypeOf(time.Time{}) {
-				return data, nil
-			}
-
-			var layout string
-			timeStr := data.(string)
-			if strings.HasSuffix(timeStr, ".000000+08:00") {
-				layout = sqlResultTimeMicroFormat
-			} else if strings.HasSuffix(timeStr, ".000+08:00") {
-				layout = sqlResultTimeMilliFormat
-			} else {
-				layout = sqlResultTimeSecFormat
-			}
-
-			return time.ParseInLocation(layout, data.(string), time.Local)
-		},
-		Result: e,
-	})
-	if err != nil {
-		return err
-	}
-
-	err = decoder.Decode(results)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}

+ 5 - 5
sql/sql_mapping.go

@@ -38,7 +38,7 @@ func ParseSqlMapping(e any) (*Mapping, error) {
 	}
 
 	if entityType.Kind() != reflect.Struct {
-		return nil, errors.New("传递的不是实体结构")
+		return nil, errors.New("传递的实体不是结构类型")
 	}
 
 	entityValue := reflect.ValueOf(e)
@@ -81,8 +81,8 @@ type MappingColumn struct {
 	OriginFieldValue reflect.Value
 
 	// 值类型的反射结构
-	ValueFieldType  reflect.Type
-	ValueFieldValue reflect.Value
+	FieldTypeElem  reflect.Type
+	FieldValueElem reflect.Value
 }
 
 func parseSqlMappingColumn(field reflect.StructField, fieldValue reflect.Value) (*MappingColumn, error) {
@@ -107,8 +107,8 @@ func parseSqlMappingColumn(field reflect.StructField, fieldValue reflect.Value)
 		AESKey:           "",
 		OriginFieldType:  field.Type,
 		OriginFieldValue: fieldValue,
-		ValueFieldType:   valueFieldType,
-		ValueFieldValue:  valueFieldValue,
+		FieldTypeElem:    valueFieldType,
+		FieldValueElem:   valueFieldValue,
 	}
 
 	if sqlColumn.Name == defaultKeyColumnName {

+ 138 - 0
sql/sql_result.go

@@ -0,0 +1,138 @@
+package sql
+
+import (
+	"errors"
+	"github.com/iancoleman/strcase"
+	"reflect"
+	"strings"
+)
+
+const (
+	sqlResultTagPartSeparator         = ";"
+	sqlResultTagPartKeyValueSeparator = ":"
+)
+
+const (
+	sqlResultTagKey    = "sqlresult"
+	sqlResultIgnore    = "-"
+	sqlResultColumn    = "column"
+	sqlResultParseTime = "parseTime"
+	sqlResultAes       = "aes"
+)
+
+type Result struct {
+	ColumnMap map[string]ResultColumn
+}
+
+func ParseSqlResult(e any) (*Result, error) {
+	if e == nil {
+		return nil, errors.New("没有传递实体")
+	}
+
+	entityType := reflect.TypeOf(e)
+	if entityType.Kind() == reflect.Ptr {
+		entityType = entityType.Elem()
+	}
+
+	if entityType.Kind() != reflect.Struct {
+		return nil, errors.New("传递的实体不是结构类型")
+	}
+
+	entityValue := reflect.ValueOf(e)
+	if entityValue.Kind() == reflect.Ptr {
+		entityValue = entityValue.Elem()
+	}
+
+	sqlResult := new(Result)
+	sqlResult.ColumnMap = make(map[string]ResultColumn)
+
+	fieldNum := entityType.NumField()
+	for i := 0; i < fieldNum; i++ {
+		field := entityType.Field(i)
+		fieldValue := entityValue.Field(i)
+
+		column, err := parseSqlResultColumn(field, fieldValue)
+		if err != nil {
+			return nil, err
+		}
+
+		if column == nil {
+			continue
+		}
+
+		sqlResult.ColumnMap[field.Name] = *column
+	}
+
+	return sqlResult, nil
+}
+
+type ResultColumn struct {
+	Name      string
+	ParseTime string
+	AESKey    string
+
+	// 原字段的反射结构
+	OriginFieldType  reflect.Type
+	OriginFieldValue reflect.Value
+
+	// 值类型的反射结构
+	FieldTypeElem  reflect.Type
+	FieldValueElem reflect.Value
+}
+
+func parseSqlResultColumn(field reflect.StructField, fieldValue reflect.Value) (*ResultColumn, error) {
+	valueFieldType := field.Type
+	valueFieldValue := fieldValue
+
+	if valueFieldType.Kind() == reflect.Ptr {
+		valueFieldType = valueFieldType.Elem()
+
+		if !valueFieldValue.IsValid() || valueFieldValue.IsNil() || valueFieldValue.IsZero() {
+			valueFieldValue = reflect.Zero(valueFieldType)
+		} else {
+			valueFieldValue = fieldValue.Elem()
+		}
+	}
+
+	sqlColumn := &ResultColumn{
+		Name:             strcase.ToSnake(field.Name),
+		ParseTime:        "",
+		AESKey:           "",
+		OriginFieldType:  field.Type,
+		OriginFieldValue: fieldValue,
+		FieldTypeElem:    valueFieldType,
+		FieldValueElem:   valueFieldValue,
+	}
+
+	sqlResultTag, ok := field.Tag.Lookup(sqlResultTagKey)
+	if !ok {
+		return sqlColumn, nil
+	}
+
+	if sqlResultTag == sqlResultIgnore {
+		return nil, nil
+	}
+
+	sqlResultParts := strings.Split(sqlResultTag, sqlResultTagPartSeparator)
+	if sqlResultParts != nil || len(sqlResultParts) != 0 {
+		for _, sqlResultPart := range sqlResultParts {
+			sqlPartKeyValue := strings.SplitN(strings.TrimSpace(sqlResultPart), sqlResultTagPartKeyValueSeparator, 2)
+			switch sqlPartKeyValue[0] {
+			case sqlResultColumn:
+				sqlColumn.Name = strings.TrimSpace(sqlPartKeyValue[1])
+			case sqlResultParseTime:
+				sqlColumn.ParseTime = strings.TrimSpace(sqlPartKeyValue[1])
+			case sqlResultAes:
+				if len(strings.TrimSpace(sqlPartKeyValue[1])) != 32 {
+					return nil, errors.New("AES密钥长度应该为32个字节")
+				}
+
+				sqlColumn.AESKey = strings.TrimSpace(sqlPartKeyValue[1])
+			default:
+				continue
+			}
+		}
+	}
+
+	return sqlColumn, nil
+}

+ 1 - 1
sql/sql_tpl/value.go

@@ -21,7 +21,7 @@ func WithAESKey(aesKey string) AfterParsedStrValueOption {
 			return "", err
 		}
 
-		return "'aes::" + encrypted + "'", nil
+		return "'" + encrypted + "'", nil
 	}
 }
 

+ 19 - 18
test/sdk_test.go

@@ -15,13 +15,13 @@ import (
 )
 
 type Class struct {
-	ID              string     `mapstructure:"id"`
-	Name            string     `sqlmapping:"updateClear;aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;" mapstructure:"name"`
-	StudentNum      int        `sqlmapping:"column:student_num;notUpdate;" mapstructure:"student_num_alias"`
-	GraduatedTime   time.Time  `mapstructure:"graduated_time"`
-	CreatedTime     *time.Time `mapstructure:"created_time"`
-	LastUpdatedTime time.Time  `mapstructure:"last_updated_time"`
-	Ignored         string     `sqlmapping:"-" mapstructure:"-"`
+	ID              string
+	Name            string `sqlmapping:"updateClear;aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;" sqlresult:"aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;"`
+	StudentNum      int    `sqlmapping:"column:student_num;notUpdate;" sqlresult:"column:student_num_alias"`
+	GraduatedTime   time.Time
+	CreatedTime     *time.Time
+	LastUpdatedTime time.Time
+	Ignored         string `sqlmapping:"-" sqlresult:"-"`
 }
 
 const (
@@ -67,7 +67,7 @@ func TestBasic(t *testing.T) {
 	insertExecuteParams, err := sql_tpl.InsertExecuteParams{
 		TableName: tableName,
 		TableRows: sql_tpl.NewTableRows().Add("id", classID).
-			Add("name", className).
+			Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Add("student_num", studentNum).
 			Add("graduated_time", now).
 			Add("created_time", now).
@@ -163,7 +163,7 @@ func TestRawSqlTemplate(t *testing.T) {
 	insertExecuteParams, err := sql_tpl.InsertExecuteParams{
 		TableName: tableName,
 		TableRows: sql_tpl.NewTableRows().Add("id", classID).
-			Add("name", className).
+			Add("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Add("student_num", studentNum).
 			Add("graduated_time", now).
 			Add("created_time", now).
@@ -183,7 +183,8 @@ func TestRawSqlTemplate(t *testing.T) {
 
 	updateExecuteParams, err := sql_tpl.UpdateExecuteParams{
 		TableName: tableName,
-		TableRows: sql_tpl.NewTableRows().Add("name", newClassName).
+		TableRows: sql_tpl.NewTableRows().
+			Add("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Add("student_num", newStudentNum),
 		Conditions: sql_tpl.NewConditions().Equal("id", classID),
 	}.Map()
@@ -196,7 +197,7 @@ func TestRawSqlTemplate(t *testing.T) {
 		SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"},
 		Conditions: sql_tpl.NewConditions().
 			Equal("id", classID).
-			Equal("name", className).
+			Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Equal("student_num", studentNum),
 		PageNo:   1,
 		PageSize: 1,
@@ -210,7 +211,7 @@ func TestRawSqlTemplate(t *testing.T) {
 		SelectColumns: []string{"id", "name", "student_num as student_num_alias", "graduated_time", "created_time", "last_updated_time"},
 		Conditions: sql_tpl.NewConditions().
 			Equal("id", classID).
-			Equal("name", newClassName).
+			Equal("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Equal("student_num", newStudentNum),
 		PageNo:   0,
 		PageSize: 0,
@@ -223,7 +224,7 @@ func TestRawSqlTemplate(t *testing.T) {
 		TableName: tableName,
 		Conditions: sql_tpl.NewConditions().
 			Equal("id", classID).
-			Equal("name", className).
+			Equal("name", className, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Equal("student_num", studentNum),
 	}.Map()
 	if err != nil {
@@ -234,7 +235,7 @@ func TestRawSqlTemplate(t *testing.T) {
 		TableName: tableName,
 		Conditions: sql_tpl.NewConditions().
 			Equal("id", classID).
-			Equal("name", newClassName).
+			Equal("name", newClassName, sql_tpl.WithAESKey("@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L")).
 			Equal("student_num", newStudentNum),
 	}.Map()
 	if err != nil {
@@ -269,7 +270,7 @@ func TestRawSqlTemplate(t *testing.T) {
 	}
 
 	classes := make([]Class, 0)
-	err = sql.ParseSqlResults(queryResults, &classes)
+	err = sql.ParseSqlTableRow(queryResults, &classes)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -307,7 +308,7 @@ func TestRawSqlTemplate(t *testing.T) {
 	}
 
 	classes = make([]Class, 0)
-	err = sql.ParseSqlResults(queryResults, &classes)
+	err = sql.ParseSqlTableRow(queryResults, &classes)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -598,7 +599,7 @@ func TestSql(t *testing.T) {
 		t.Fatal("总数不正确")
 	}
 
-	err = sql.ParseSqlResults(tableRows, &queryClasses)
+	err = sql.ParseSqlTableRow(tableRows, &queryClasses)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -624,7 +625,7 @@ func TestSql(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	err = sql.ParseSqlResults(tableRow, queryClass)
+	err = sql.ParseSqlTableRow(tableRow, queryClass)
 	if err != nil {
 		t.Fatal(err)
 	}