56、Go语言基础 - 数据库操作 - Go 操作 MySQL
hi,我是温新
Go 语言中操作 MySQL 数据库通常需要使用第三方库,最常用的库是github.com/go-sql-driver/mysql
,它提供了 Go 语言与 MySQL 数据库交互的接口。
准备工作
创建数据表
CREATE TABLE `user_infos` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`sex` tinyint NOt NULL DEFAULT 1,
`email` varchar(260) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `nations` (
country varchar(50)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
安装第三方包
go get github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx
连接数据库
sqlx.Open
打开数据库连接。
sqlx.Open(driverName string, dataSourceName string) (*DB, error)
-
driverName
(字符串):要使用的数据库驱动程序的名称,例如 "mysql"、"postgres" 等。 -
dataSourceName
(字符串):包含数据库连接信息的数据源名称。这个字符串通常包括用户名、密码、数据库地址和名称,如 "username:password@tcp(localhost:3306)/databasename"
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
// 数据库连接信息
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
// 使用 sqlx.Open 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
// 测试连接数据库
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
fmt.Println("MySQL 数据库连接成功")
}
insert
db.Exec
是 jmoiron/sqlx
包中的一个函数,用于执行 SQ L语句,通常用于执行不需要返回结果集的SQL操作,如插入、更新、删除数据等。
func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error)
-
db
:*DB
类型,代表数据库连接对象。 -
query
: 字符串,包含要执行的SQL语句,可以包含参数占位符。 -
args
: 任意数量的参数,用于替换SQL语句中的占位符。
返回值:
-
sql.Result
: 表示执行SQL操作后的结果对象。通常包含受影响的行数等信息。 -
error
: 如果执行SQL语句过程中出现错误,将返回一个非空的错误对象。
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
// 插入数据
insertSQL := "INSERT INTO user_infos (username, sex, email) VALUES (?, ?, ?)"
res, err := db.Exec(insertSQL, "王美丽", 1, "wangmeili@ziruchu.com")
if err != nil {
fmt.Println("数据插入失败", err)
return
}
id, err := res.LastInsertId()
if err != nil {
fmt.Println("操作失败, ", err)
return
}
fmt.Println("插入数据成功, ID 为", id)
}
select
Db.Select
是 jmoiron/sqlx
包中的一个函数,用于执行SQL查询语句,并将结果映射到 Go 结构体切片。
func (db *DB) Select(dest interface{}, query string, args ...interface{}) error
-
db
:*DB
类型,代表数据库连接对象。 -
dest
: 接口,表示目标,通常是一个空的结构体切片,用于接收查询结果的映射。 -
query
: 字符串,包含要执行的SQL查询语句,可以包含参数占位符。 -
args
: 任意数量的参数,用于替换SQL语句中的占位符。
返回值:
-
error
: 如果执行SQL查询语句过程中出现错误,将返回一个非空的错误对象。
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
// 数据库连接信息
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
// 使用 sqlx.Open 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
// 测试数据库连接
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
// 查询数据并映射到结构体切片
var userInfos []UserInfo
err = db.Select(&userInfos, "SELECT id, username, sex, email FROM user_infos")
if err != nil {
fmt.Println("数据查询失败:", err)
return
}
fmt.Println("查询数据成功:", userInfos)
// 遍历数据并输出
for _, userInfo := range userInfos {
fmt.Printf("Id:%d, 姓名:%s, 邮箱:%s\n", userInfo.ID, userInfo.Username, userInfo.Email)
}
}
// UserInfo 结构体用于映射数据库中的 user_infos 表
type UserInfo struct {
ID int `db:"id"`
Username string `db:"username"`
Sex int `db:"sex"`
Email string `db:"email"`
}
update
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
// 数据库连接信息
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
// 使用 sqlx.Open 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
// 测试数据库连接
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
// 更新数据
updateSQL := "UPDATE user_infos SET username = ? WHERE id = ?"
// 执行更新操作并获取结果
res, err := db.Exec(updateSQL, "王小丽", 2)
if err != nil {
fmt.Println("数据更新失败:", err)
return
}
// 获取受影响的行数
rowsAffected, err := res.RowsAffected()
if err != nil {
fmt.Println("获取受影响的行数失败, ", err)
}
fmt.Println("数据更新成功,受影响的行数:", rowsAffected)
}
这个示例连接到数据库,执行一个更新操作,将ID为2的用户的用户名更新为"王小丽"。然后,它获取并输出受影响的行数,以确认更新操作成功。
delete
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
// 数据库连接信息
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
// 使用 sqlx.Open 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
// 测试数据库连接
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
// 删除数据
deleteSQL := "DELETE FROM user_infos WHERE id = ?"
res, err := db.Exec(deleteSQL, 2)
if err != nil {
fmt.Println("数据删除失败:", err)
return
}
// 获取受影响的行数
row, err := res.RowsAffected()
if err != nil {
fmt.Println("获取受影响的行数失败, ", err)
}
fmt.Println("数据删除成功,受影响的行数:", row)
}
事务
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
// 数据库连接信息
dsn := "root:123456@tcp(192.168.31.90:3306)/test"
// 使用 sqlx.Open 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
fmt.Println("数据库打开失败", err)
return
}
defer db.Close()
// 测试数据库连接
err = db.Ping()
if err != nil {
fmt.Println("数据库连接失败", err)
return
}
// 开启事务
tx, err := db.Begin()
if err != nil {
fmt.Println("事务启动失败:", err)
return
}
// 用户信息插入
_, err = tx.Exec("INSERT INTO user_infos (username, sex, email) VALUES (?, ?, ?)", "王丽丽", 1, "wanglili@ziruchu.com")
if err != nil {
// 如果插入失败,回滚事务
tx.Rollback()
fmt.Println("用户信息写入失败:", err)
return
}
// 国家信息插入
_, err = tx.Exec("INSERT INTO nations (country) VALUES (?)", "中国")
if err != nil {
// 如果插入失败,回滚事务
tx.Rollback()
fmt.Println("国家信息插入失败:", err)
return
}
// 提交事务
err = tx.Commit()
if err != nil {
fmt.Println("事务提交失败:", err)
return
}
fmt.Println("事务执行成功")
}
这个示例连接到数据库,开启一个事务,然后插入用户信息和国家信息。如果任何一个插入操作失败,它会回滚整个事务以确保数据一致性。如果两个插入操作都成功,它会提交事务。
请登录后再评论