[gogf/gf]orm读取字段类型decimal精度丢失

2024-06-25 343 views
6

golang 1.13 gf1.10.1 orm数据库读取字段为decimal类型时超过一定长度会发生数据精度丢失,结构体类型定义为string 转结构体跟字符串都会丢失精度

查询代码

func GetCumNumByMeIdAndCurId(meId int, curId string) (*Entity, error) {
    Model := g.DB("default").Table(Table).Safe()
    entityStruct := new(Entity)
    err := Model.Where("me_id=?", meId).Where("cur_id=?", curId).Struct(entityStruct)
    value, err := Model.Where("me_id=?", meId).Where("cur_id=?", curId).Fields("cum_num").Value()
    fmt.Println(value.String())
    return entityStruct, err
}

回答

5

@zhangHongBo21 你好,我看了下decimal类型自动生成的Entity属性中使用的是float64类型,应该不会出现精度问题的。能否提供可复现问题的完整最小的代码。

4
// Entity is the golang structure for table qkl_currency_money.
type Entity struct {
    CumId        int    `orm:"cum_id,primary" json:"cum_id"`         // 主键 id       
    MeId         int    `orm:"me_id"          json:"me_id"`          // 用户 id       
    CurId        int    `orm:"cur_id"         json:"cur_id"`         // 币种 id       
    CumNum       string `orm:"cum_num"        json:"cum_num"`        // 币种可用数量  
    CumFrozenNum string `orm:"cum_frozen_num" json:"cum_frozen_num"` // 币种冻结数量  
    CumAddress   string `orm:"cum_address"    json:"cum_address"`    // 充币地址      
}

这个是cli自动生成的结构体,我手动改一下吧

1

不好意思,手动修改结构体类型为float64也会发生精度丢失,是我的数字实在是太大了,99999999999999999999999999999999999999999999999999999999999999999这个是测试用的数据

9
// Entity is the golang structure for table qkl_currency_money.
type Entity struct {
    CumId        int     `orm:"cum_id,primary" json:"cum_id"`         // 主键 id
    MeId         int     `orm:"me_id"          json:"me_id"`          // 用户 id
    CurId        int     `orm:"cur_id"         json:"cur_id"`         // 币种 id
    CumNum       string  `orm:"cum_num"        json:"cum_num"`        // 币种可用数量
    CumFrozenNum float64 `orm:"cum_frozen_num" json:"cum_frozen_num"` // 币种冻结数量
    CumAddress   string  `orm:"cum_address"    json:"cum_address"`    // 充币地址
}

上述是结构体,然后具体的model方法,精度丢失是在执行sql的地方

func GetCumNumByMeIdAndCurId(meId int, curId string) (*Entity, error) {
    Model := g.DB("default").Table(Table).Safe()
    entityStruct := new(Entity)
//在这里就发生了精度丢失,不管是我修改为字符串或者是浮点都会丢失
    err := Model.Where("me_id=?", meId).Where("cur_id=?", curId).Struct(entityStruct)
    link := g.Cfg().GetString("database.link")
    link = strings.Replace(link, "mysql:", "", -1)
//最后没有办法了,用了xorm,虽然现在是测试阶段,但是也还是可能会发生精度丢失的问题,就用xorm单查一个字段
    engine, err := xorm.NewEngine("mysql", link)
    sqlStr := fmt.Sprintf("SELECT cum_num FROM `qkl_currency_money` WHERE cum_id=%d", entityStruct.CumId)
    ceshi := ""
    _, err = engine.SQL(sqlStr).Get(&ceshi)
    entityStruct.CumNum = ceshi
    return entityStruct, err
}
4

@zhangHongBo21 你那个数据太大了,不是精度的问题了。

0

@ zhangHongBo21你那个数据太大了,不是精度的问题了。 没有办法,区块链的破玩意,数据就是很大,我最后实在是没办法用xorm单查一个字段,感觉性能损耗实在是太严重了。所以,还是尽量弄一哈哈

7

@zhangHongBo21 你在数据库字段中的数值是什么?转换出来的数值是什么?丢失的精度是什么?可以使用gconv.Struct单独创建一个独立的示例试试。