关于Go与GORM最近遇到的坑

其实老生常谈了,通过Struct映射数据库与JSON的时候,datetime类型会有各种异常,解决如下:

// Import package
import (
	"database/sql/driver"
	"fmt"
	"strconv"
	"time"
)

// 定义一个JSONDate类型
type JSONDate struct {
	time.Time
}

// 定义JSON构建与解析函数
func (t JSONDate) MarshalJSON() ([]byte, error) {
	formatted := fmt.Sprintf("\"%s\"", t.Format("2006-01-02"))
	return []byte(formatted), nil
}

func (t *JSONDate) UnmarshalJSON(data []byte) error {
	uq, _ := strconv.Unquote(string(data))
	value, err := time.ParseInLocation("2006-01-02", uq, time.Local)
	if err == nil {
		*t = JSONDate{Time: value}
		return nil
	}
	return err
}

// 定义数据库支持函数
func (t JSONDate) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}

func (t *JSONDate) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = JSONDate{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}

// 定义Model
type User struct {
	Date   JSONDate        `json:"date"`
}

还遇到一个问题,关于货币类型的数据,在数据库中一般是以decimal类型存储,有时也会乘以100或者10000以integer存储。而在gorm中,因为float的长度和精度问题,不能满足需求,经过各种弯路,找到一个相对靠谱的方法:

import "github.com/shopspring/decimal"

type Bill struct {
	Amount decimal.Decimal `gorm:"type:decimal(10,2)" json:"amount,string"`
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注