在 Go 语言中,sqlx
包是一个用于数据库操作的库,它建立在标准库的 database/sql
包之上,并提供了一些额外的功能,以简化和增强与数据库的交互。sqlx
的目标是通过提供更方便的 API 和一些附加功能来改善在 Go 中进行 SQL 数据库查询的体验。
以下是 sqlx
包的一些主要特性:
结构体映射: sqlx
允许将数据库查询的结果映射到 Go 结构体中,简化了数据的处理和访问。
命名参数: 支持使用命名参数执行查询,使得 SQL 语句更易读且更易维护。
Null 值支持: 对于可能为 NULL 的字段,sqlx
提供了 null
类型,以方便地处理这些情况。
更丰富的查询方法: sqlx
提供了一些额外的查询方法,如 Get
、Select
,使得执行查询更加方便。
数据库连接池: 支持数据库连接池,提高了在并发环境中的性能。
支持多种数据库: sqlx
可以与多种数据库一起使用,包括 PostgreSQL、MySQL、SQLite 等。
原生 SQL 支持: sqlx
支持使用原生的 SQL 语句,同时也支持使用预处理语句。
扫描任意类型: sqlx
具有更灵活的 Scan
方法,可以直接将查询结果映射到任意类型。
总体而言,sqlx
提供了一些额外的工具和功能,使得在 Go 语言中进行数据库查询更加方便、灵活,同时也提高了代码的可读性和可维护性。如果你在 Go 中进行 SQL 数据库操作,sqlx
是一个值得考虑的库。
go get "github.com/jmoiron/sqlx"
go get "github.com/go-sql-driver/mysql"
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
// 准备数据库的连接参数信息
var (
userName string = "root"
passWord string = "12345678"
ipAddress string = "127.0.0.1"
port string = "3306"
dbName string = "go_test"
charset string = "utf8mb4"
)
// 链接mysql
func connectSql() *sqlx.DB {
//root:12345678@tcp(127.0.0.1:3306)/go_test?charset=utf8mb4
dbStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", userName,
passWord,
ipAddress,
port,
dbName,
charset)
//使用匿名变量忽略err
DB, _ := sqlx.Open("mysql", dbStr)
//数据库连接池优化
//DB.SetConnMaxLifetime() 设置连接的最大生存时间为5分钟
//DB.SetConnMaxIdleTime() 设置连接的最大空闲时间为10分钟
// 设置连接池大小
//db.SetMaxOpenConns(10) // 设置最大打开连接数
//db.SetMaxIdleConns(5) // 设置最大空闲连接数
ping(DB)
return DB
}
// 测试连接 调用DB对象的原始函数 ping()
func ping(db *sqlx.DB) {
err := db.Ping()
if err != nil {
fmt.Println("ping失败", err)
} else {
fmt.Println("ping成功")
}
}
func main() {
mysqlDB := connectSql()
defer mysqlDB.Close()
}
先在本地创建一个测试用的数据库表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`userid` int(11) NULL DEFAULT NULL COMMENT '用户id',
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密码',
`avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户头像',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
func main() {
mysqlDB := connectSql()
defer mysqlDB.Close()
//新增
insertSql := "insert into user(userid,username,password,avatar,create_time,update_time) values (?,?,?,?,?,?)"
result, err := mysqlDB.Exec(insertSql, 1, "xiaoming", "12345678", "a.png", time.Now().Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05"))
if err != nil {
fmt.Println("数据插入失败", err)
return
}
//查询新增后的最新的id
id, _ := result.LastInsertId()
fmt.Println(id)
//修改
updateSql := "update user set username = 'hahaha' where id =1"
result2, err2 := mysqlDB.Exec(updateSql)
if err2 != nil {
fmt.Println("数据更新失败", err2)
return
}
num, _ := result2.RowsAffected()
fmt.Println("影响的数据行数", num)
//删除
deleteSql := "delete from user where id =1"
result3, _ := mysqlDB.Exec(deleteSql)
num2, _ := result3.RowsAffected()
fmt.Println("影响的数据行数", num2)
}
mysqlDB := connectSql()
defer mysqlDB.Close()
//基础类型存储
querySql := "select * from user"
rows, _ := mysqlDB.Query(querySql)
for rows.Next() {
var id, userId int
var username, password, avatar, create_time, update_time string
rows.Scan(&id, &userId, &username, &password, &avatar, &create_time, &update_time)
fmt.Println(id, userId, username, password, avatar, create_time, update_time)
}
rows.Close()
fmt.Println(rows)
//利用结构体、切片存储数据
//需要与数据库内的所有字段一一映射,不一致会导致查询后的解析失败
type user struct {
Id int `db:"id"`
UserId int `db:"userid"`
UserName string `db:"username"`
Password string `db:"password"`
Avatar string `db:"avatar"`
CreateTime string `db:"create_time"`
UpdateTime string `db:"update_time"`
}
//查询单条
userData := new(user)
mysqlDB.Get(userData, "select * from user where id =2")
fmt.Println(userData)
//查询所有
var userSlice []user
//需要传入切片地址
err := mysqlDB.Select(&userSlice, "select * from user")
if err != nil {
fmt.Println(err)
}
fmt.Println(userSlice)