mysql bit 对gorm使用何种类型?

最近项目里面需要查询某一张表,改表某个字段xxx的类型是bit,然后自以为是的使用go的bool来接收该字段值,结果不出意外就出意外了。报错:

 sql/driver: couldn't convert "\x01" into type 

可见,在底层解析过程中,并不能把mysql的bit类型转化成go的bool。

 我们跟踪源码进去底层可以看到,在database/sql/driver/type.go 文件中对目标为bool类型的处理如下

var Bool boolType

type boolType struct{}

var _ ValueConverter = boolType{}

func (boolType) String() string { return "Bool" }

func (boolType) ConvertValue(src any) (Value, error) {
	switch s := src.(type) {
	case bool:
		return s, nil
	case string:
		b, err := strconv.ParseBool(s)
		if err != nil {
			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
		}
		return b, nil
	case []byte:
		b, err := strconv.ParseBool(string(s))
		if err != nil {
			return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s)
		}
		return b, nil
	}

 // XXXXXXXX 略
}

目前我们在查询mysql后拿到的src 其实是[]uint8类型(实际上就是 []byte),接着就进入了case []byte 分支,然后这里直接把原数据通过string(s) 强制转换成字符串,导致原来的值 0x01 变成了字符面值为  SOH (通过查看ASCII表)代表标题开始的字符。所以调用strconv.ParseBool 必定失败,因为s根本不符合bool字符量。从而导致错误发生。那么我们要怎么处理这种类型呢?

其实sql包提供了,scan接口:如下

type Scanner interface {
	// Scan assigns a value from a database driver.
	//
	// The src value will be of one of the following types:
	//
	//    int64
	//    float64
	//    bool
	//    []byte
	//    string
	//    time.Time
	//    nil - for NULL values
	//
	// An error should be returned if the value cannot be stored
	// without loss of information.
	//
	// Reference types such as []byte are only valid until the next call to Scan
	// and should not be retained. Their underlying memory is owned by the driver.
	// If retention is necessary, copy their values before the next call to Scan.
	Scan(src any) error
}

只要你的类型实现了该接口,那么就可以操作bit类型了,于是我自定义了类型来接收bit类型。


type MyBool bool

func (b *MyBool) Value() (driver.Value, error) {
	result := make([]uint8, 1)
	if *b {
		result[0] = uint8(1)
	} else {
		result[0] = 0
	}
	return result, nil
}
func (b *MyBool) Scan(v interface{}) error {
	bytes := v.([]uint8)

	if bytes[0] == 0 {
		*b = false
	} else {
		*b = true
	}
	return nil
}

在对应字段上使用该类型,你就可以接受mysql 的bit类型了。(注意这里类型的方法一定是指针对应的方法,否者赋值失败)

相关推荐

  1. mysql bit gorm使用类型

    2024-07-11 17:58:04       26 阅读
  2. 使用 GORM 自定义类型:解决问题与技巧分享

    2024-07-11 17:58:04       26 阅读
  3. gorm 使用sql方法

    2024-07-11 17:58:04       46 阅读
  4. Gorm 入门介绍与基本使用

    2024-07-11 17:58:04       43 阅读
  5. Gorm 关联关系介绍与基本使用

    2024-07-11 17:58:04       46 阅读
  6. Golang gorm 结构体定义使用

    2024-07-11 17:58:04       42 阅读
  7. 【Golang】使用 GORM 的 Scopes 进行查询

    2024-07-11 17:58:04       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 17:58:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 17:58:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 17:58:04       58 阅读
  4. Python语言-面向对象

    2024-07-11 17:58:04       69 阅读

热门阅读

  1. python爬虫学习(三十三天)---多线程上篇

    2024-07-11 17:58:04       22 阅读
  2. 一、Python 日志系统设计之不同级别的系统日志

    2024-07-11 17:58:04       20 阅读
  3. SpringAMQP收发消息demo

    2024-07-11 17:58:04       20 阅读
  4. SpringSecurity中文文档(Servlet OAuth 2.0 Login)

    2024-07-11 17:58:04       19 阅读
  5. ant-design-vue表格设置某列标题部分文字颜色

    2024-07-11 17:58:04       24 阅读
  6. python-redis-lock是如何实现锁自动续期的

    2024-07-11 17:58:04       22 阅读
  7. APK反编译

    2024-07-11 17:58:04       25 阅读