Golang中使用MySQL操作数据模型的实践指南

Golang中使用MySQL操作数据模型的实践指南

go-models

go-models 是一个轻量且易于使用的模型库。这个仓库只是一个示例。

模块列表如下:


特性

这是一个带有数据对象模型的SQL查询构建器。
并且提供了一种简单的方式来构建您的数据逻辑层以访问redis。
这是一种从数据库访问数据的简单方法,让您专注于数据处理逻辑。
目前支持MySQL、MariaDB、Redis

计划支持:PostgreSQL、MSSQL、SQLite、Mongodb等...
  • 由于原始驱动程序的扩展,字段扫描变得更加容易。 假设:我们有5个字段需要扫描
type Tb struct {
	field0 sql.NullString,
	field1 sql.NullString,
	field2 sql.NullString,
	field3 sql.NullString,
	field4 sql.NullString,
}

在原始驱动程序中,它不能动态处理。有多少个字段,您就必须写多少个字段。如果您有20个字段,您必须写20次。

var tb Tb
err = rows.Scan(&tb.field0, &tb.field1, &tb.field2, &tb.field3, &tb.field4)

在go-models-mysql中,您只需填充结构体的nil指针。

if val, err = myDao.ScanRowType(row, (*Tb)(nil)); err == nil {
	u, _ := val.(*Tb)
	fmt.Println("Tb", u)
}
  • DAO层让您更直观地操作mysql。
    • 原始驱动程序(sql.DB)已扩展,因此您可以操作原始命令。
      • 例如:Query、QueryRow、Exec等…
    • 导入sqlbuilder可以轻松访问sql数据库。
myDao.Select("Host", "User", "Select_priv").From("user").Where("User='root'").Limit(1)
  • 在DAO中设置默认表,您可以友好地设计您的dao层。
// 为dao设置一个结构体作为默认模型(可选)
// (*UserTb)(nil) : UserTb结构体的nil指针
// "user" : 数据库中的实际表名
myUserDao.SetDefaultModel((*UserTb)(nil), "user")

// 调用模型的Get(),获取user表中的所有行
// 返回 (rows *sql.Rows, err error)
rows, err = myDao.Get()

要求

* Go 1.12 或更高版本。
* [database/sql](https://golang.org/pkg/database/sql/) 包
* [go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) 包
* [go-redis/redis](https://github.com/go-redis/redis) 包

Go模块

在您的包文件夹中创建go.mod文件,并填写以下内容

module github.com/eehsiao/go-models-example

go 1.13

require (
	github.com/eehsiao/go-models-lib latest
	github.com/eehsiao/go-models-mysql latest
	github.com/eehsiao/go-models-redis latest
	github.com/eehsiao/sqlbuilder latest
	github.com/go-redis/redis v6.15.5+incompatible
	github.com/go-sql-driver/mysql v1.4.1
)

Docker

轻松启动测试环境。您可以运行示例代码。

$ docker-compose up -d

使用

import (
    "database/sql"
	"fmt"

	mysql "github.com/eehsiao/go-models-mysql"
	redis "github.com/eehsiao/go-models-redis"
)

// UserTb : 要存储到mysql的sql表结构体
type UserTb struct {
	Host       sql.NullString `TbField:"Host"`
	User       sql.NullString `TbField:"User"`
	SelectPriv sql.NullString `TbField:"Select_priv"`
}

// User : 要存储到redis的json结构体
type User struct {
	Host       string `json:"host"`
	User       string `json:"user"`
	SelectPriv string `json:"select_priv"`
}

// 新建mysql dao
myUserDao := &MyUserDao{
    Dao: mysql.NewDao().SetConfig("root", "mYaDmin", "127.0.0.1:3306", "mysql").OpenDB(),
}

// 示例1:直接使用sqlbuilder
myUserDao.Select("Host", "User", "Select_priv").From("user").Where("User='root'").Limit(1)
fmt.Println("sqlbuilder", myUserDao.BuildSelectSQL())
if row, err = myUserDao.GetRow(); err == nil {
    if val, err = myUserDao.ScanRowType(row, (*UserTb)(nil)); err == nil {
        u, _ := val.(*UserTb)
        fmt.Println("UserTb", u)
    }
}
    
// 为dao设置一个结构体作为默认模型(可选)
// (*UserTb)(nil) : UserTb结构体的nil指针
// "user" : 数据库中的实际表名
myUserDao.SetDefaultModel((*UserTb)(nil), "user")

// 调用模型的Get(),获取user表中的所有行
// 返回 (rows *sql.Rows, err error)
rows, err = myDao.Get()

// 调用模型的GetRow(),获取user行中的第一行
// 返回 (row *sql.Row, err error)
row, err = myDao.GetRow()


// 新建redis dao
redUserModel := &RedUserModel{
    Dao: redis.NewDao().SetConfig("127.0.0.1:6379", "", 0).OpenDB(),
}

// 为dao设置一个结构体作为默认模型(可选)
// (*User)(nil) : User结构体的nil指针
// "user" : 数据库中的实际表名
SetDefaultModel((*User)(nil), "user")

lib.Iif : 是一个内联IF-ELSE逻辑
lib.Struct4Scan : 将对象结构体转换为指针切片,便于扫描sql结果。
lib.Struce4Query : 将结构体转换为sql选择字段的字符串。例如 "idx, name"。
lib.Struce4QuerySlice : 将结构体转换为[]string切片。
lib.Serialize : 将对象序列化为json字符串。

SqlBuilder

sqlbuilder是递归调用函数,您可以轻松构建sql字符串

例如:dao.Select().From().Join().Where().Limit()

SqlBuilder函数

  • 构建select:
    • Select(s …string)
    • Distinct(b bool)
    • Top(i int)
    • From(s …string)
    • Where(s string)
    • WhereAnd(s …string)
    • WhereOr(s …string)
    • Join(s string, c string)
    • InnerJoin(s string, c string)
    • LeftJoin(s string, c string)
    • RightJoin(s string, c string)
    • FullJoin(s string, c string)
    • GroupBy(s …string)
    • OrderBy(s …string)
    • OrderByAsc(s …string)
    • OrderByDesc(s …string)
    • Having(s string)
    • BuildSelectSQL()
  • 构建update:
    • Set(s map[string]interface{})
    • FromOne(s string)
    • BuildUpdateSQL()
  • 构建insert:
    • Into(s string)
    • Fields(s …string)
    • Values(s …[]interface{})
    • BuildInsertSQL()
  • 构建delete:
    • BuildDeleteSQL()
  • 通用:
    • ClearBuilder()
    • BuildedSQL()
    • SetDbName(s string)
    • SetTbName(s string)
    • SwitchPanicToErrorLog(b bool)
    • PanicOrErrorLog(s string)

示例

1 内置示例

example.go

该示例将连接到本地mysql并获取用户数据。 然后连接到本地redis并设置用户数据,并重新获取。

2 示例

https://github.com/eehsiao/go-models-example/

操作指南

如何设计模型数据逻辑

MySQL

1.

创建一个表结构体,并添加标签TbField:"实际表字段"

TbField标签是必需的。实际表字段也必须与表字段相同。

type UserTb struct {
	Host       sql.NullString `TbField:"Host"`
	User       sql.NullString `TbField:"User"`
	SelectPriv sql.NullString `TbField:"Select_priv"`
}

2.

使用Struce4QuerySlice生成sqlbuilder的选择字段

m := mysql.NewDao().SetConfig("root", "mYaDmin", "127.0.0.1:3306", "mysql").OpenDB()
m.Select(lib.Struce4QuerySlice(m.DaoStructType)...).From(m.TbName).Limit(3)

3.

将sql结果扫描到结构体对象中

row, err = m.GetRow()
if val, err = m.ScanRowType(row, (*UserTb)(nil)); err == nil {
    u, _ := val.(*UserTb)
    fmt.Println("UserTb", u)
}

Redis

1.

创建一个数据结构体,并添加标签json:"名称"

type User struct {
	Host       string `json:"host"`
	User       string `json:"user"`
	SelectPriv string `json:"select_priv"`
	IntVal     int    `json:"user,string"`
}

如果您有整数值,可以添加转换类型描述。 例如json:“user,string

2.

创建redis dao

m := redis.NewDao().SetConfig("127.0.0.1:6379", "", 0).OpenDB()

3.

直接使用go-redis命令函数

redBool, err = m.HSet(userTable, redKey, serialStr).Result()

更多关于Golang中使用MySQL操作数据模型的实践指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用MySQL操作数据模型的实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是针对 go-models 库在 Golang 中操作 MySQL 数据模型的实践指南的专业分析。我将重点说明核心功能、代码示例和关键操作步骤,不涉及建议或自我描述。

核心特性与优势

go-models 通过扩展标准 database/sql 驱动和集成 sqlbuilder,简化了 MySQL 数据模型操作。主要优势包括:

  • 动态字段扫描:无需手动指定每个字段,使用 ScanRowType 自动处理结构体映射。
  • DAO 层抽象:通过设置默认模型和表名,统一数据访问逻辑。
  • SQL 构建器:链式调用生成复杂查询,减少手写 SQL 错误。

实践步骤与代码示例

1. 定义数据模型结构体

使用 TbField 标签映射数据库字段,确保与表结构一致。示例:

type UserTb struct {
    Host       sql.NullString `TbField:"Host"`
    User       sql.NullString `TbField:"User"`
    SelectPriv sql.NullString `TbField:"Select_priv"`
}

2. 初始化 MySQL DAO 并设置默认模型

配置数据库连接并指定默认模型和表名:

myUserDao := mysql.NewDao().SetConfig("root", "mYaDmin", "127.0.0.1:3306", "mysql").OpenDB()
myUserDao.SetDefaultModel((*UserTb)(nil), "user")

3. 使用 SQL 构建器执行查询

通过链式调用构建 SELECT 查询,并自动扫描结果到结构体:

rows, err := myUserDao.Select("Host", "User", "Select_priv").From("user").Where("User='root'").Limit(1).Get()
if err != nil {
    // 处理错误
}
row, err := myUserDao.GetRow()
if val, err := myUserDao.ScanRowType(row, (*UserTb)(nil)); err == nil {
    user := val.(*UserTb)
    fmt.Printf("User: %s, Host: %s\n", user.User.String, user.Host.String)
}

4. 批量操作与字段生成

利用 lib.Struce4QuerySlice 自动生成查询字段,避免硬编码:

fields := lib.Struce4QuerySlice(myUserDao.DaoStructType)
myUserDao.Select(fields...).From("user").Where("Host='localhost'").Get()

5. 插入和更新数据

使用 SQL 构建器进行 INSERT 和 UPDATE 操作:

// INSERT 示例
myUserDao.Into("user").Fields("Host", "User", "Select_priv").Values([]interface{}{"localhost", "newuser", "Y"}).BuildInsertSQL()
result, err := myUserDao.Exec()

// UPDATE 示例
myUserDao.FromOne("user").Set(map[string]interface{}{"Select_priv": "N"}).Where("User='newuser'").BuildUpdateSQL()
result, err := myUserDao.Exec()

6. 错误处理与连接管理

始终检查数据库操作错误,并确保连接正确关闭:

defer myUserDao.Close()
if err != nil {
    log.Printf("Database error: %v", err)
}

与 Redis 集成示例

go-models 支持 Redis 操作,通过类似模式序列化数据:

type User struct {
    Host       string `json:"host"`
    User       string `json:"user"`
    SelectPriv string `json:"select_priv"`
}
redDao := redis.NewDao().SetConfig("127.0.0.1:6379", "", 0).OpenDB()
redDao.SetDefaultModel((*User)(nil), "user")
serialized, _ := lib.Serialize(User{Host: "localhost", User: "redisuser"})
err := redDao.HSet("user:key", "data", serialized).Err()

总结

go-models 通过结合 SQL 构建器和动态扫描机制,显著提升了 Golang 中 MySQL 数据模型的操作效率。示例代码演示了从模型定义到查询、更新的完整流程,适用于需要高效数据访问的应用程序。

回到顶部