根据官网文档 Go Wiki: SQL Database Drivers - The Go Programming Language 可以看到go可以连接的关系型数据库
常用的关系型数据库基本上都支持,下面以mysql为例
下载mysql驱动
打开上面的mysql链接 GitHub - go-sql-driver/mysql: Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package
注意:
从 Go 1.16 版本开始,go get
命令在没有模块的情况下不再被支持。现在,Go 强烈推荐使用模块管理依赖。要在你的项目中使用第三方库,你需要先创建一个模块。
首先,你需要进入你的项目目录,并初始化一个新的 Go 模块。在命令行中执行以下命令:
go mod init your_module_name
执行如下命令 (所在文件夹下必须有mod文件)
go get -u github.com/go-sql-driver/mysql
下载好后会在${GOPATH}/pkg目录下下载好依赖
编写go代码连接mysql
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 设置 MySQL 数据库连接信息
dataSourceName := "root:123456@tcp(192.168.31.131:3306)/gotest"
// 打开数据库连接
db, err := sql.Open("mysql", dataSourceName)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 尝试连接数据库
err = db.Ping()
if err != nil {
log.Fatal("Could not connect to the database:", err)
}
fmt.Println("Connected to the MySQL database!")
// 连接成功后,可以执行数据库操作,例如查询或插入数据
// 例如,查询数据库中的数据
rows, err := db.Query("SELECT * FROM album")
if err != nil {
log.Fatal("Error querying database:", err)
}
defer rows.Close()
// 遍历查询结果
for rows.Next() {
var id int
var title string
var artist string
var price []uint8
if err := rows.Scan(&id, &title, &artist, &price); err != nil {
log.Fatal(err)
}
fmt.Println("id=> ", id, " title=> ", title, " artist=> ", artist, " price=>", string(price))
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}
数据库操作
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db := getDb()
defer db.Close()
//执行操作代码
}
func getDb() *sql.DB {
// 设置 MySQL 数据库连接信息
dataSourceName := "root:123456@tcp(192.168.31.131:3306)/gotest"
// 打开数据库连接
db, err := sql.Open("mysql", dataSourceName)
if err != nil {
log.Fatal(err)
}
// 尝试连接数据库
err = db.Ping()
if err != nil {
log.Fatal("Could not connect to the database:", err)
}
return db
}
预编译
只需要将sql中的参数变为? 后面加上就可以了
查询
查询一条
QueryRow
最多检索单个数据库行,例如当您想通过唯一 ID 查找数据时。如果查询返回多行,该 Scan
方法将丢弃除第一行之外的所有行。
func getOne(db *sql.DB) {
row := db.QueryRow("select * from stu where id=1")
//row := db.QueryRow("select * from stu")
if row.Err() != nil {
fmt.Println("查询失败")
return
}
var stu Stu
err := row.Scan(&stu.id, &stu.name, &stu.age, &stu.address)
if err != nil {
fmt.Println("查询失败err")
return
}
fmt.Println(stu)
}
这边如果查出来多条记录则只会取第一条
查询多条
Query您可以使用或查询多行QueryContext,它返回Rows表示查询结果的 。您的代码使用 迭代返回的行Rows.Next。每次迭代都会调用Scan将列值 复制到变量中。
func getMany(db *sql.DB) {
rows, err := db.Query("select * from stu")
if err != nil {
fmt.Println("查询失败")
return
}
defer rows.Close()
stus := make([]Stu, 0)
for rows.Next() {
stu := Stu{}
err := rows.Scan(&stu.id, &stu.name, &stu.age, &stu.address)
if err != nil {
fmt.Println("赋值失败")
return
}
stus = append(stus, stu)
}
fmt.Println("=============")
fmt.Println(stus)
}
增加
新增一条
func insertOne(db *sql.DB) {
_, err := db.Exec("insert into stu(name,age,address) values (?,?,?)", "新增名字", 11, "新增地址")
if err != nil {
fmt.Println("插入失败", err)
return
}
fmt.Println("插入成功")
}
新增多条
新增多条就需要事务
func insertMany(db *sql.DB) {
insertSql := "insert into stu(name,age,address) values (?,?,?)"
tx, err := db.Begin()
if err != nil {
fmt.Println("开启事务失败")
return
}
prepare, err := tx.Prepare(insertSql)
if err != nil {
fmt.Println("预编译失败")
return
}
defer prepare.Close()
stus := make([]Stu, 0)
for i := 0; i < 10; i++ {
stus = append(stus, Stu{
id: i,
name: "批量新增名字" + strconv.Itoa(i),
age: i,
address: "批量新增地址" + strconv.Itoa(i),
})
}
for _, stu := range stus {
_, err := prepare.Exec(stu.name, stu.age, stu.address)
if err != nil {
fmt.Println("插入失败")
return
}
}
tx.Commit()
fmt.Println("批量插入成功")
}
修改
更新一条
func updateOne(db *sql.DB) {
updateSql := "update stu set name=?,age=? where id=?"
prepare, err := db.Prepare(updateSql)
if err != nil {
fmt.Println("预编译失败")
return
}
_, err = prepare.Exec("更新名称", 22, 62)
if err != nil {
fmt.Println("更新失败", err)
return
}
fmt.Println("更新成功")
}
更新多条
更新多条需要使用事务
func updateMany(db *sql.DB) {
updateSql := "update stu set address=? where id=?"
tx, err := db.Begin()
if err != nil {
fmt.Println("开启事务失败")
return
}
prepare, err := tx.Prepare(updateSql)
if err != nil {
fmt.Println("预编译失败")
return
}
defer prepare.Close()
stus := make([]Stu, 0)
for i := 2; i < 10; i++ {
stus = append(stus, Stu{
id: i + 60,
address: "批量更新地址" + strconv.Itoa(i),
})
}
for _, stu := range stus {
_, err := prepare.Exec(stu.address, stu.id)
if err != nil {
fmt.Println("批量更新失败")
return
}
}
tx.Commit()
fmt.Println("批量更新成功")
}
删除
删除一个
func deleteOne(db *sql.DB) {
deleteSql := "delete from stu where id=?"
prepare, err := db.Prepare(deleteSql)
if err != nil {
fmt.Println("预编译失败")
return
}
_, err = prepare.Exec(62)
if err != nil {
fmt.Println("删除失败", err)
return
}
fmt.Println("删除成功")
}
删除多个
func deleteMany(db *sql.DB) {
deleteSql := "delete from stu where id in (?,?)"
prepare, err := db.Prepare(deleteSql)
if err != nil {
fmt.Println("预编译失败")
return
}
_, err = prepare.Exec(63, 64)
if err != nil {
fmt.Println("批量删除失败", err)
return
}
fmt.Println("批量删除成功")
}
事务
开启事务
tx, err := db.Begin()
提交事务
tx.Commit()
回滚事务
tx.Rollback()