res := common.DB.Create(reqType) reqType是一个接口,底层是结构体 怎么取出结构体id值
时间: 2024-02-02 20:03:13 浏览: 32
在 Golang 中,可以使用类型断言来将接口类型转换为具体的结构体类型,然后获取结构体的 ID 值。具体可以参考下面的示例代码:
```
// 假设 reqType 是一个指向结构体的接口类型,底层是结构体 PsPipe
// 将接口类型转换为具体的结构体类型
pipe, ok := reqType.(*models.PsPipe)
if !ok {
// 类型断言失败,处理错误逻辑
}
// 获取结构体的 ID 值
id := pipe.ID
```
在上面的示例代码中,首先使用类型断言将接口类型转换为具体的结构体类型,然后通过访问结构体的 ID 字段来获取其 ID 值。如果类型断言失败,则表示接口类型不是 PsPipe 类型,可以在此处处理错误逻辑。
相关问题
简化这段代码switch item.Type { //雨水口 case "cumb": req := models.PsComb{} if err := mapstructure.Decode(item.Value, &req); err != nil { panic(err) } res := common.DB.Create(&req) if res.Error != nil { resp.Code = 500 resp.Msg = "创建失败" resp.Data = res.Error ctx.JSON(500, resp) return } //生成CombID common.DB.Model(&req).Update("CombID", "P"+"01"+req.Code+strconv.Itoa(int(req.ID))) resp.Data = req.CombID ctx.JSON(200, resp) // case "conduit": req := models.PsConduit{} if err := mapstructure.Decode(item.Value, &req); err != nil { panic(err) } res := common.DB.Create(&req) if res.Error != nil { resp.Code = 500 resp.Msg = "创建失败" resp.Data = res.Error ctx.JSON(500, resp) return } //生成ConduitID common.DB.Model(&req).Update("ConduitID", "L"+"02"+req.Code+strconv.Itoa(int(req.ID))) resp.Data = req.ConduitID ctx.JSON(200, resp) case "feature": req := models.Feature{} if err := mapstructure.Decode(item.Value, &req); err != nil { panic(err) } res := common.DB.Create(&req) if res.Error != nil { resp.Code = 500 resp.Msg = "创建失败" resp.Data = res.Error ctx.JSON(500, resp) return } //生成FeatureID common.DB.Model(&req).Update("FeatureID", "P"+"10"+req.Code+strconv.Itoa(int(req.ID))) resp.Data = req.FeatureID ctx.JSON(200, resp) }
可以使用 map 来简化这段代码,将每个 case 表达式与一个对应的结构体以及生成 ID 的前缀进行映射,然后根据输入的 item.Type 从 map 中获取对应的结构体和前缀,再执行相应的操作。以下是代码示例:
```go
package main
import (
"strconv"
"github.com/gin-gonic/gin"
"github.com/mitchellh/mapstructure"
)
type Request interface{}
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
type ItemType struct {
Type string `json:"type"`
Value Request `json:"value"`
}
type PrefixID struct {
Prefix string
ID string
}
var prefixMap = map[string]PrefixID{
"cumb": PrefixID{"P01", "CombID"},
"conduit": PrefixID{"L02", "ConduitID"},
"feature": PrefixID{"P10", "FeatureID"},
}
var modelMap = map[string]interface{}{
"cumb": &models.PsComb{},
"conduit": &models.PsConduit{},
"feature": &models.Feature{},
}
func createItem(ctx *gin.Context) {
var item ItemType
var resp Response
if err := ctx.ShouldBindJSON(&item); err != nil {
resp.Code = 400
resp.Msg = "参数错误"
ctx.JSON(400, resp)
return
}
if reqType, ok := modelMap[item.Type]; ok {
if err := mapstructure.Decode(item.Value, reqType); err != nil {
panic(err)
}
res := common.DB.Create(reqType)
if res.Error != nil {
resp.Code = 500
resp.Msg = "创建失败"
resp.Data = res.Error
ctx.JSON(500, resp)
return
}
prefixID := prefixMap[item.Type]
common.DB.Model(reqType).Update(prefixID.ID, prefixID.Prefix+strconv.Itoa(int(reqType.ID)))
resp.Data = prefixID.Prefix + strconv.Itoa(int(reqType.ID))
ctx.JSON(200, resp)
} else {
resp.Code = 400
resp.Msg = "参数错误"
ctx.JSON(400, resp)
}
}
```
在上面的代码中,我们使用了 prefixMap 和 modelMap 来分别将每个 case 表达式与一个对应的前缀以及结构体进行了映射。在 createItem 函数中,我们根据输入的 item.Type 从 modelMap 中获取对应的结构体,然后使用 mapstructure.Decode 函数将 item.Value 解码成对应的结构体。接着,我们使用 common.DB.Create 函数将结构体写入数据库,生成对应的 ID,并使用 common.DB.Model 函数更新 ID 字段。最后,我们根据输入的 item.Type 从 prefixMap 中获取对应的前缀,将前缀和 ID 拼接起来作为返回值。
优化代码 var modelMap = map[string]interface{}{ "comb": &models.PsComb{}, "conduit": &models.PsConduit{}, "feature": &models.Feature{}, "discharger": &models.PsDischarger{}, "gate": &models.PsGate{}, "interception": &models.PsInterception{}, "lake": &models.PsLake{}, "manhole": &models.PsManhole{}, "outfall": &models.PsOutfall{}, "pipe": &models.PsPipe{}, "pumpStation": &models.PsPumpStation{}, "retention": &models.PsRetention{}, "river": &models.PsRiver{}, "wwtp": &models.PsWWTP{}, "psSystem": &models.PsSystem{}, "landUse": &models.LandUse{}, "publicity": &models.Publicity{}, } func Batch(ctx *gin.Context) { var requ Request if err := ctx.ShouldBind(&requ); err != nil { ctx.JSON(400, models.Response{ Code: 400, Msg: "参数有误", Data: err.Error(), }) return } resp := models.Response{ Code: 0, Msg: "success", } for _, item := range requ.Post { if reqType, ok := modelMap[item.Type]; ok { if err := mapstructure.Decode(item.Value, reqType); err != nil { panic(err) } res := common.DB.Create(reqType) if res.Error != nil { resp.Code = 500 resp.Msg = "创建失败" resp.Data = res.Error ctx.JSON(500, resp) return } ctx.JSON(200, resp)
这段代码看起来比较简单,但可以从以下几个方面进行优化:
1. 将 `modelMap` 改为在 `init()` 函数中初始化,而不是在每次调用 `Batch()` 函数时初始化。这样可以避免重复初始化,提高代码的性能。
2. 针对循环中的每个 `item`,可以采用批量插入(bulk insert)的方式,而不是逐个插入。这样可以减少数据库交互的次数,提高代码的性能。例如,可以将所有待插入的数据构造成一个切片,然后通过 `common.DB.CreateInBatches()` 方法进行批量插入。
3. 当出现错误时,应该立即返回错误信息,而不是继续进行循环。这样可以避免不必要的数据库交互和数据错误。
下面是一个优化后的示例代码:
```
var modelMap = map[string]interface{}{
"comb": &models.PsComb{},
"conduit": &models.PsConduit{},
"feature": &models.Feature{},
"discharger": &models.PsDischarger{},
"gate": &models.PsGate{},
"interception": &models.PsInterception{},
"lake": &models.PsLake{},
"manhole": &models.PsManhole{},
"outfall": &models.PsOutfall{},
"pipe": &models.PsPipe{},
"pumpStation": &models.PsPumpStation{},
"retention": &models.PsRetention{},
"river": &models.PsRiver{},
"wwtp": &models.PsWWTP{},
"psSystem": &models.PsSystem{},
"landUse": &models.LandUse{},
"publicity": &models.Publicity{},
}
func init() {
for _, model := range modelMap {
common.DB.AutoMigrate(model)
}
}
func Batch(ctx *gin.Context) {
var requ Request
if err := ctx.ShouldBind(&requ); err != nil {
ctx.JSON(400, models.Response{
Code: 400,
Msg: "参数有误",
Data: err.Error(),
})
return
}
resp := models.Response{
Code: 0,
Msg: "success",
}
var values []interface{}
for _, item := range requ.Post {
if reqType, ok := modelMap[item.Type]; ok {
if err := mapstructure.Decode(item.Value, reqType); err != nil {
ctx.JSON(500, models.Response{
Code: 500,
Msg: "创建失败",
Data: err.Error(),
})
return
}
values = append(values, reqType)
}
}
if len(values) > 0 {
res := common.DB.CreateInBatches(values, len(values))
if res.Error != nil {
ctx.JSON(500, models.Response{
Code: 500,
Msg: "创建失败",
Data: res.Error,
})
return
}
}
ctx.JSON(200, resp)
}
```
注意,这只是一种示例代码,具体实现可能需要根据您的实际情况进行调整。