Битовый тип MySQL соответствует какому типу Go?

Раньше я использовал Java, поэтому тип некоторых столбцов в таблице базы данных — bit(1). Но теперь я хочу использовать beego для перестроения моего проекта, и я не хочу изменять свою таблицу базы данных (многое нужно сделать). Я использую beego's 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

person JICHUN    schedule 28.11.2017    source источник
comment
Во-первых, вы должны использовать BOOL в MySQL, если ваш тип соответствует логическому значению (судя по имени). Надеемся, что после того, как вы внесете это изменение, ответ на ваш фактический вопрос будет очевиден.   -  person Flimzy    schedule 28.11.2017
comment
Но я думаю, что не могу изменить тип. Старая программа Java работает сейчас. Я не уверен, что старая программа будет работать правильно после моего изменения.   -  person JICHUN    schedule 28.11.2017
comment
Если вам необходимо использовать эту схему, это отстой, но продолжайте. Но мой комментарий все же должен помочь ответить на ваш вопрос.   -  person Flimzy    schedule 28.11.2017
comment
Хорошо, позвольте мне попробовать в тестовых условиях. Спасибо.   -  person JICHUN    schedule 28.11.2017


Ответы (2)


Sqlx также создал собственный тип данных bool для таких ситуаций, и он отлично работает. Ссылка на соответствующий код

// 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
}
person Tarmo    schedule 20.09.2019
comment
Функцию сканирования можно использовать следующим образом; var valOrg interface{} var valBB types.BitBool var val bool .... err = query.Scan(..., &valOrg,...) .... err = valBB.Scan(valOrg) val = bool(valBB ) - person udayanga; 20.01.2021

Итак, какой тип 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
}
person Flimzy    schedule 28.11.2017