yjp 1 gadu atpakaļ
vecāks
revīzija
e8fd22b38c

+ 30 - 16
binding/service/entity_crud/service.go

@@ -9,9 +9,9 @@ import (
 	"git.sxidc.com/go-framework/baize/infrastructure"
 	"git.sxidc.com/go-framework/baize/infrastructure/database"
 	"git.sxidc.com/go-framework/baize/infrastructure/database/sql"
+	"git.sxidc.com/go-framework/baize/tag/sql/sql_mapping"
 	"git.sxidc.com/go-tools/utils/strutils"
 	"git.sxidc.com/service-supports/fserr"
-	"git.sxidc.com/service-supports/fslog"
 	"reflect"
 )
 
@@ -129,28 +129,44 @@ func CommonEntityUpdate(tableName string, databaseExecutorType string, callbacks
 	}
 }
 
-func CommonEntityQuery[O any](tableName string, databaseExecutorType string, callbacks *Callbacks[*response.InfosData[O]], conditionFieldCallback domain.ConditionFieldCallback) binding.ServiceFunc[*response.InfosData[O]] {
-	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (*response.InfosData[O], error) {
+func CommonEntityQuery[O any](tableName string, databaseExecutorType string, callbacks *Callbacks[response.InfosData[O]], conditionFieldCallback domain.ConditionFieldCallback) binding.ServiceFunc[response.InfosData[O]] {
+	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[O], error) {
 		dbExecute := i.ChooseDBExecutor(databaseExecutorType)
 
 		queryDTO, ok := dto.(request.Query)
 		if !ok {
-			return &response.InfosData[O]{}, fserr.New("DTO不是Query")
+			return response.InfosData[O]{}, fserr.New("DTO不是Query")
 		}
 
 		e, ok := objects[0].(domain.Entity)
 		if !ok {
-			return &response.InfosData[O]{}, fserr.New("需要传递领域对象应该为实体")
+			return response.InfosData[O]{}, fserr.New("需要传递领域对象应该为实体")
 		}
 
-		conditions, err := e.QueryDBConditions(conditionFieldCallback)
+		conditions := sql.NewConditions()
+
+		fields, err := sql_mapping.DefaultUsage(e)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecute, &response.InfosData[O]{})
+			return response.InfosData[O]{}, err
+		}
+
+		for _, field := range fields {
+			hasDeal := false
+			if conditionFieldCallback != nil {
+				hasDeal = conditionFieldCallback(conditions, field.FieldName, field.ColumnName, field.Value)
+			}
+
+			if !hasDeal {
+				fieldValue := reflect.ValueOf(field.Value)
+				if !fieldValue.IsZero() {
+					conditions.Equal(field.ColumnName, field.Value)
+				}
+			}
 		}
 
 		err = callbackBeforeDBOperate(callbacks, e, dbExecute)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecute, &response.InfosData[O]{})
+			return callbackOnError(callbacks, e, err, dbExecute, response.InfosData[O]{})
 		}
 
 		results, totalCount, err := database.Query(dbExecute, &sql.QueryExecuteParams{
@@ -160,16 +176,16 @@ func CommonEntityQuery[O any](tableName string, databaseExecutorType string, cal
 			PageSize:   queryDTO.GetPageSize(),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecute, &response.InfosData[O]{})
+			return callbackOnError(callbacks, e, err, dbExecute, response.InfosData[O]{})
 		}
 
 		infos := make([]O, 0)
 		err = sql.ParseSqlResult(results, &infos)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecute, &response.InfosData[O]{})
+			return callbackOnError(callbacks, e, err, dbExecute, response.InfosData[O]{})
 		}
 
-		output := &response.InfosData[O]{
+		output := response.InfosData[O]{
 			Infos:      infos,
 			TotalCount: totalCount,
 			PageNo:     queryDTO.GetPageNo(),
@@ -183,12 +199,10 @@ func CommonEntityQueryByID[O any](tableName string, databaseExecutorType string,
 	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (O, error) {
 		var outputZero O
 		outputZeroValue := reflect.Zero(reflect.TypeOf(outputZero))
-		if outputZeroValue.Kind() != reflect.Pointer {
-			fslog.Error("建议在QueryByID时使用指针类型作为输出,以方便对查询结果进行后处理")
+		if outputZeroValue.Kind() == reflect.Pointer {
+			outputZeroValue.Set(reflect.New(outputZeroValue.Type().Elem()))
 		}
 
-		outputZeroValue.Set(reflect.New(outputZeroValue.Type().Elem()))
-
 		dbExecute := i.ChooseDBExecutor(databaseExecutorType)
 
 		e, ok := objects[0].(domain.Entity)
@@ -198,7 +212,7 @@ func CommonEntityQueryByID[O any](tableName string, databaseExecutorType string,
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecute, nil)
+			return callbackOnError(callbacks, e, err, dbExecute, outputZero)
 		}
 
 		err := callbackBeforeDBOperate(callbacks, e, dbExecute)

+ 0 - 23
domain/entity.go

@@ -2,7 +2,6 @@ package domain
 
 import (
 	"git.sxidc.com/go-framework/baize/infrastructure/database/sql"
-	"git.sxidc.com/go-framework/baize/tag/sql/sql_mapping"
 	"git.sxidc.com/go-tools/utils/strutils"
 	"git.sxidc.com/service-supports/fserr"
 )
@@ -16,7 +15,6 @@ type Entity interface {
 	GetID() string
 	CheckID(errCode int) error
 	IDColumnName() string
-	QueryDBConditions(callback ConditionFieldCallback) (*sql.Conditions, error)
 }
 
 type BaseEntity struct {
@@ -51,24 +49,3 @@ func (e *BaseEntity) CheckID(errCode int) error {
 func (e *BaseEntity) IDColumnName() string {
 	return ColumnID
 }
-
-func (e *BaseEntity) QueryDBConditions(callback ConditionFieldCallback) (*sql.Conditions, error) {
-	fields, err := sql_mapping.DefaultUsage(e)
-	if err != nil {
-		return nil, err
-	}
-
-	conditions := sql.NewConditions()
-	for _, field := range fields {
-		hasDeal := false
-		if callback != nil {
-			hasDeal = callback(conditions, field.FieldName, field.ColumnName, field.Value)
-		}
-
-		if !hasDeal {
-			conditions.Equal(field.ColumnName, field.Value)
-		}
-	}
-
-	return conditions, nil
-}

+ 32 - 132
examples/binding/main.go

@@ -2,30 +2,28 @@ package main
 
 import (
 	"git.sxidc.com/go-framework/baize"
-	"git.sxidc.com/go-framework/baize/api"
 	"git.sxidc.com/go-framework/baize/application"
 	"git.sxidc.com/go-framework/baize/binding"
 	"git.sxidc.com/go-framework/baize/binding/request"
 	"git.sxidc.com/go-framework/baize/binding/response"
+	"git.sxidc.com/go-framework/baize/binding/service/entity_crud"
 	"git.sxidc.com/go-framework/baize/domain"
 	"git.sxidc.com/go-framework/baize/infrastructure"
-	"git.sxidc.com/go-framework/baize/infrastructure/database"
 	"git.sxidc.com/go-framework/baize/infrastructure/database/operations"
-	"git.sxidc.com/go-framework/baize/infrastructure/database/sql"
-	"git.sxidc.com/go-tools/utils/strutils"
 	DEATH "github.com/vrecan/death"
 	"syscall"
 	"time"
 )
 
-// curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' "http://localhost:10100/test/v1/class/create"
-// curl -X PUT -H "Content-Type: application/json" -d '{"id":"ab0d4a9acce44ddd91ad4746ecd34392", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
-// curl -X GET "http://localhost:10100/test/v1/class/query?name=test-new&pageNo=0&pageSize=1"
-// curl -X GET "http://localhost:10100/test/v1/class/get?id=ab0d4a9acce44ddd91ad4746ecd34392"
-// curl -X DELETE "http://localhost:10100/test/v1/class/ab0d4a9acce44ddd91ad4746ecd34392/delete"
+// curl -X POST -H "Content-Type: application/json" -d '{"name":"test", "studentNum": 10}' "http://localhost:10100/test/v1/class/create"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"10ec51a6485b4fadb9fc1b4f1360b8d0", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
+// curl -X GET "http://localhost:10100/test/v1/class/query?name=test-new&pageNo=1&pageSize=1"
+// curl -X GET "http://localhost:10100/test/v1/class/get?id=10ec51a6485b4fadb9fc1b4f1360b8d0"
+// curl -X DELETE "http://localhost:10100/test/v1/class/10ec51a6485b4fadb9fc1b4f1360b8d0/delete"
 
 type CreateClassJsonBody struct {
-	Name string `json:"name" binding:"required" assign:"toField:Name"`
+	Name       string `json:"name" binding:"required" assign:"toField:Name"`
+	StudentNum int    `json:"studentNum" binding:"required" assign:"toField:StudentNum"`
 }
 
 type DeleteClassPathParams struct {
@@ -33,27 +31,25 @@ type DeleteClassPathParams struct {
 }
 
 type UpdateClassJsonBody struct {
-	ID   string `json:"id" binding:"required" assign:"toField:ID"`
-	Name string `json:"name" assign:"toField:Name"`
+	ID         string `json:"id" binding:"required" assign:"toField:ID"`
+	Name       string `json:"name" assign:"toField:Name"`
+	StudentNum int    `json:"studentNum" assign:"toField:StudentNum"`
 }
 
 type QueryClassesQueryParams struct {
-	Name     string `form:"name" assign:"toField:Name"`
-	PageNo   int    `form:"pageNo" assign:"-"`
-	PageSize int    `form:"pageSize" assign:"-"`
+	Name       string `form:"name" assign:"toField:Name"`
+	StudentNum int    `form:"studentNum" assign:"toField:StudentNum"`
+	request.BaseQuery
 }
 
 type GetClassQueryParams struct {
 	ID string `form:"id" binding:"required" assign:"toField:ID"`
 }
 
-type DomainIDField struct {
-	ID string `sqlmapping:"column:id"`
-}
-
 type Class struct {
-	*DomainIDField
+	domain.BaseEntity
 	Name            string `sqlmapping:"column:name"`
+	StudentNum      int    `sqlmapping:"column:student_num"`
 	CreatedTime     time.Time
 	LastUpdatedTime *time.Time
 }
@@ -65,6 +61,7 @@ type InfoIDField struct {
 type ClassInfo struct {
 	*InfoIDField
 	Name            string `json:"name" sqlresult:"column:name"`
+	StudentNum      int    `json:"studentNum" sqlresult:"column:student_num"`
 	CreatedTime     string `sqlresult:"parseTime:'2006-01-02 15:04:05'"`
 	LastUpdatedTime string `sqlresult:"parseTime:'2006-01-02 15:04:05'"`
 }
@@ -115,6 +112,13 @@ func main() {
 				NotNull: true,
 				Index:   true,
 			},
+			{
+				Name:    "student_num",
+				Type:    "integer",
+				Comment: "学生数量",
+				NotNull: true,
+				Index:   true,
+			},
 			{
 				Name:    "created_time",
 				Type:    "timestamp with time zone",
@@ -147,17 +151,7 @@ func main() {
 		ResponseFunc: response.SendIDResponse[string],
 		DTO:          &CreateClassJsonBody{},
 		Objects:      []domain.Object{&Class{}},
-		ServiceFunc: func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (string, error) {
-			e := domain.ToConcrete[*Class](objects[0])
-			e.ID = strutils.SimpleUUID()
-
-			err := database.InsertEntity(i.DBOperations(), tableName, e)
-			if err != nil {
-				return "", err
-			}
-
-			return e.ID, nil
-		},
+		ServiceFunc:  entity_crud.CommonEntityCreate(tableName, infrastructure.DBExecutorOperations, nil),
 	})
 
 	// 删除班级
@@ -166,16 +160,7 @@ func main() {
 		ResponseFunc: response.SendMsgResponse,
 		DTO:          &DeleteClassPathParams{},
 		Objects:      []domain.Object{&Class{}},
-		ServiceFunc: func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
-			e := domain.ToConcrete[*Class](objects[0])
-
-			err := database.DeleteEntity(i.DBOperations(), tableName, e)
-			if err != nil {
-				return "", err
-			}
-
-			return nil, nil
-		},
+		ServiceFunc:  entity_crud.CommonEntityDelete(tableName, infrastructure.DBExecutorOperations, nil),
 	})
 
 	// 修改班级
@@ -184,38 +169,7 @@ func main() {
 		ResponseFunc: response.SendMsgResponse,
 		DTO:          &UpdateClassJsonBody{},
 		Objects:      []domain.Object{&Class{}},
-		ServiceFunc: func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
-			e := domain.ToConcrete[*Class](objects[0])
-
-			result, err := database.QueryOne(i.DBOperations(), &sql.QueryOneExecuteParams{
-				TableName:  tableName,
-				Conditions: sql.NewConditions().Equal("id", e.ID),
-			})
-			if err != nil {
-				return nil, err
-			}
-
-			existClass := new(Class)
-			err = sql.ParseSqlResult(result, existClass)
-			if err != nil {
-				return nil, err
-			}
-
-			newEntity := &Class{
-				DomainIDField: &DomainIDField{ID: existClass.ID},
-			}
-
-			if strutils.IsStringNotEmpty(e.Name) && e.Name != existClass.Name {
-				newEntity.Name = e.Name
-			}
-
-			err = database.UpdateEntity(i.DBOperations(), tableName, newEntity)
-			if err != nil {
-				return "", err
-			}
-
-			return nil, nil
-		},
+		ServiceFunc:  entity_crud.CommonEntityUpdate(tableName, infrastructure.DBExecutorOperations, nil),
 	})
 
 	// 查询班级
@@ -224,70 +178,16 @@ func main() {
 		ResponseFunc: response.SendInfosResponse[ClassInfo],
 		DTO:          &QueryClassesQueryParams{},
 		Objects:      []domain.Object{&Class{}},
-		ServiceFunc: func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[ClassInfo], error) {
-			e := domain.ToConcrete[*Class](objects[0])
-			pageNo := dto.Field[int](dto, "PageNo")
-			pageSize := dto.Field[int](dto, "PageSize")
-
-			conditions := sql.NewConditions()
-
-			if strutils.IsStringNotEmpty(e.Name) {
-				conditions.Equal("name", e.Name)
-			}
-
-			results, totalCount, err := database.Query(i.DBOperations(), &sql.QueryExecuteParams{
-				TableName:  tableName,
-				Conditions: conditions,
-				PageNo:     pageNo,
-				PageSize:   pageSize,
-			})
-			if err != nil {
-				return response.InfosData[ClassInfo]{
-					Infos: make([]ClassInfo, 0),
-				}, nil
-			}
-
-			classInfos := make([]ClassInfo, 0)
-			err = sql.ParseSqlResult(results, &classInfos)
-			if err != nil {
-				return response.InfosData[ClassInfo]{
-					Infos: make([]ClassInfo, 0),
-				}, nil
-			}
-
-			return response.InfosData[ClassInfo]{
-				Infos:      classInfos,
-				TotalCount: totalCount,
-				PageNo:     pageNo,
-			}, nil
-		},
+		ServiceFunc:  entity_crud.CommonEntityQuery[ClassInfo](tableName, infrastructure.DBExecutorOperations, nil, nil),
 	})
 
 	// 通过ID获取班级
-	binding.GetBind(binder, &binding.SimpleBindItem[*ClassInfo]{
+	binding.GetBind(binder, &binding.SimpleBindItem[ClassInfo]{
 		Path:         "/class/get",
-		ResponseFunc: response.SendInfoResponse[*ClassInfo],
+		ResponseFunc: response.SendInfoResponse[ClassInfo],
 		DTO:          &GetClassQueryParams{},
-		Objects:      []domain.Object{&Class{}},
-		ServiceFunc: func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (*ClassInfo, error) {
-			e := domain.ToConcrete[*Class](objects[0])
-
-			result, err := database.QueryOne(i.DBOperations(), &sql.QueryOneExecuteParams{
-				TableName:  tableName,
-				Conditions: sql.NewConditions().Equal("id", e.ID),
-			})
-			if err != nil {
-				return nil, err
-			}
-
-			info := new(ClassInfo)
-			err = sql.ParseSqlResult(result, info)
-			if err != nil {
-				return nil, err
-			}
-
-			return info, nil
-		},
+		Objects:      []domain.Object{Class{}},
+		ServiceFunc:  entity_crud.CommonEntityQueryByID[ClassInfo](tableName, infrastructure.DBExecutorOperations, nil),
 	})
 
 	go func() {

+ 3 - 3
infrastructure/database/sql/value.go

@@ -29,13 +29,13 @@ func toSqlValue(value any) (string, error) {
 	case time.Time:
 		return "'" + v.Format(timeWriteFormat) + "'", nil
 	default:
-		var retStr string
-		err := reflectutils.AssignStringValue(v, reflect.ValueOf(retStr))
+		retStr := new(string)
+		err := reflectutils.AssignStringValue(v, reflect.ValueOf(retStr).Elem())
 		if err != nil {
 			return "", err
 		}
 
-		return retStr, nil
+		return *retStr, nil
 	}
 }