mysql的位类型映射golang的类型

时间:2017-11-28 15:45:48

标签: mysql go orm beego

之前我使用过Java,因此数据库表中的某些列类型为bit(1)。但现在我想使用beego重建我的项目,我不想改变我的数据库表(需要做很多)。我在我的项目中使用了beego的orm。那么我应该使用哪种Go类型?

这样的表和删除的列有问题:

+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | varchar(255) | NO   | PRI | NULL    |       |
| created_time | datetime     | YES  |     | NULL    |       |
| deleted      | bit(1)       | NO   |     | NULL    |       |
| updated_time | datetime     | YES  |     | NULL    |       |
| icon_class   | varchar(255) | YES  |     | NULL    |       |
| mark         | varchar(255) | YES  |     | NULL    |       |
| name         | varchar(255) | YES  |     | NULL    |       |
| parent       | varchar(255) | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+

像这样结构:

type BaseModel struct {
    Id          string           `orm:"pk";form:"id"`
    CreatedTime time.Time        `orm:"auto_now_add;type(datetime)";form:"-"`
    UpdatedTime time.Time        `orm:"auto_now;type(datetime)";form:"-"`
    Deleted     bool `form:"-"`
}

当我在代码中使用bool时,错误如下:

`[0]` convert to `*orm.BooleanField` failed, field: shareall-go/models.Category.BaseModel.Deleted err: strconv.ParseBool: parsing "\x00": invalid syntax

2 个答案:

答案 0 :(得分:1)

Sqlx还为这种情况创建了一个自定义的bool数据类型,并且工作正常。 Link to related code

// BitBool is an implementation of a bool for the MySQL type BIT(1).
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
type BitBool bool

// Value implements the driver.Valuer interface,
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
func (b BitBool) Value() (driver.Value, error) {
    if b {
        return []byte{1}, nil
    } else {
        return []byte{0}, nil
    }
}

// Scan implements the sql.Scanner interface,
// and turns the bitfield incoming from MySQL into a BitBool
func (b *BitBool) Scan(src interface{}) error {
    v, ok := src.([]byte)
    if !ok {
        return errors.New("bad []byte type assertion")
    }
    *b = v[0] == 1
    return nil
}

答案 1 :(得分:0)

  

我应该使用哪种Go类型?

通常,这取决于您使用数据的方式多于存储方式。正如您所想,您尝试将其用作Bool(这是有道理的)但是出错了。

问题是MySQL存储BIT的方式与存储BOOL的方式不同,Go MySQL驱动程序需要MySQL BOOL。您可以使用实现sql.Scanner接口的自定义类型来解决此问题。因为你可能只有两个(或者三个,如果算上NULL)输入,它应该相当容易。请注意,此代码不完整且未经测试。它旨在作为指南,而不是复制和粘贴解决方案。

type MyBool bool

func (b *MyBool) Scan(src interface{}) error {
    str, ok := src.(string)
    if !ok {
        return fmt.Errorf("Unexpected type for MyBool: %T", src)
    }
    switch str {
    case "\x00":
        v := false
        *b = v
    case "\x01":
        v := true
        *b = v
    }
    return nil
}