Golang中如何将MySQL的tinyint类型保存到数据表
Golang中如何将MySQL的tinyint类型保存到数据表 我有一个MySQL字段,其类型为tinyint,而Go结构体中的对应字段是布尔类型。
保存时报告未能成功保存。
应如何处理此问题
4 回复
如果我拥有十万条记录。我的循环是不必要的
更多关于Golang中如何将MySQL的tinyint类型保存到数据表的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你需要将布尔值映射为整数,例如:
type User struct {
Username string
Email string
Acitve bool
}
u := new(User)
var active int
stmt.QueryRow(email).Scan(&u.Username, &u.Email, &active)
if active == 0 {
u.Active = false
} else {
u.Active = true
}
可以尝试使用 ent
这是一个示例结构体
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
)
type Demo struct {
ent.Schema
}
func (Demo) Fields() []ent.Field {
return []ent.Field{
field.Uint64("id").Unique(),
field.String("name"),
field.Bool("is_delete"),
}
}
func (Demo) Edges() []ent.Edge {
return []ent.Edge{}
}
func (DhExpert) Demo() []schema.Annotation {
return []schema.Annotation{entsql.Annotation{Table: "demo"}}
}
可以像这样进行 Create 操作:
sdn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", "root", "123456", "192.168.1.203", 3306, "ent_test")
client, err := ent.Open("mysql", sdn)
if err != nil {
log.Fatalf("failed opening connection to sqlite: %v", err)
}
defer client.Close()
ctx := context.Background()
// Run the auto migration tool.
if err := client.Schema.Create(ctx); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
// create
cli.Debug().Demo.Create().SetID(1).SetName("xx").SetIsDelete(false).SaveX(ctx)
// query
xx, _ := client.Demo.Query().All(context.Background())
for _, v := range xx {
fmt.Printf("%v\n", v)
}
在Golang中处理MySQL的tinyint(1)与bool类型的映射,需要使用sql.NullBool类型或实现database/sql的Scanner和Valuer接口。以下是具体解决方案:
方案一:使用sql.NullBool(推荐)
import (
"database/sql"
"fmt"
)
type User struct {
ID int64
Name string
// 使用sql.NullBool替代bool
Active sql.NullBool
}
// 插入数据示例
func createUser(db *sql.DB, user *User) error {
_, err := db.Exec(
"INSERT INTO users (name, active) VALUES (?, ?)",
user.Name,
user.Active,
)
return err
}
// 查询数据示例
func getUser(db *sql.DB, id int64) (*User, error) {
var user User
err := db.QueryRow(
"SELECT id, name, active FROM users WHERE id = ?",
id,
).Scan(&user.ID, &user.Name, &user.Active)
if err != nil {
return nil, err
}
return &user, nil
}
// 使用示例
func main() {
user := &User{
Name: "John Doe",
Active: sql.NullBool{
Bool: true,
Valid: true, // 设置为true表示该字段有效
},
}
// 检查布尔值
if user.Active.Valid && user.Active.Bool {
fmt.Println("User is active")
}
}
方案二:自定义类型实现Scanner和Valuer接口
import (
"database/sql"
"database/sql/driver"
"fmt"
)
// 自定义Bool类型
type Bool bool
// Scan实现Scanner接口
func (b *Bool) Scan(value interface{}) error {
if value == nil {
*b = false
return nil
}
switch v := value.(type) {
case int64:
*b = v != 0
case bool:
*b = Bool(v)
default:
return fmt.Errorf("unsupported type: %T", value)
}
return nil
}
// Value实现Valuer接口
func (b Bool) Value() (driver.Value, error) {
return bool(b), nil
}
type Product struct {
ID int64
Name string
// 使用自定义Bool类型
InStock Bool
}
// 使用示例
func handleProduct(db *sql.DB) error {
// 插入
product := &Product{
Name: "Laptop",
InStock: true,
}
_, err := db.Exec(
"INSERT INTO products (name, in_stock) VALUES (?, ?)",
product.Name,
product.InStock, // 自动调用Value()方法
)
if err != nil {
return err
}
// 查询
var p Product
err = db.QueryRow(
"SELECT id, name, in_stock FROM products WHERE name = ?",
"Laptop",
).Scan(&p.ID, &p.Name, &p.InStock) // 自动调用Scan()方法
if err != nil {
return err
}
fmt.Printf("Product in stock: %v\n", bool(p.InStock))
return nil
}
方案三:使用GORM ORM
如果使用GORM,它会自动处理这种映射:
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type Customer struct {
gorm.Model
Name string
Active bool `gorm:"type:tinyint(1)"`
}
func main() {
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
// 自动迁移
db.AutoMigrate(&Customer{})
// 创建记录
customer := Customer{
Name: "Alice",
Active: true,
}
db.Create(&customer)
// 查询
var result Customer
db.First(&result, "name = ?", "Alice")
fmt.Printf("Customer active status: %v\n", result.Active)
}
直接使用database/sql的原始查询
// 对于简单的查询,可以直接使用int类型接收
type SimpleUser struct {
ID int64
Name string
Active int // 使用int类型接收tinyint
}
func getSimpleUser(db *sql.DB, id int64) (*SimpleUser, error) {
var user SimpleUser
err := db.QueryRow(
"SELECT id, name, active FROM users WHERE id = ?",
id,
).Scan(&user.ID, &user.Name, &user.Active)
if err != nil {
return nil, err
}
// 手动转换
isActive := user.Active == 1
fmt.Printf("Is active: %v\n", isActive)
return &user, nil
}
选择哪种方案取决于具体需求:
- 需要处理NULL值:使用
sql.NullBool - 需要类型安全且简洁:使用自定义类型实现接口
- 使用ORM:GORM会自动处理
- 简单场景:直接使用int类型接收并手动转换

