Go开发之数据操作
聊点科技新闻
1.何恺明github主页宣布将于 2024 年加入麻省理工学院(MIT)电气工程与计算机科学系(EECS),成为一名教师。何许人也? 1984 年生于广东广州的何恺明,事业上基本一路狂飙,只有自己搜索一下才知道这位天才有多么厉害。不过也值得思考,这么优秀的人才…
2.nodejs安全发布预警:我们将在 2023 年 8 月 8 日或之后不久发布 v16、v18 和 v20 发行版的新版本。目前最新版本20.5.0,稳定版本为18.17.0
3.8月5日,上海举办由kubesphere主办的AI+serverless的交流会。在上海的朋友有福了,可以去参加交流交流。
再说说go中数据库处理
这列就以mysql为例分享一下:
1.安装mysql驱动
三方开源的mysql库: github.com/go-sql-driver/mysql (mysql驱动)
github.com/jmoiron/sqlx (基于mysql驱动的封装)
可以使用以下命令来安装github.com/go-sql-driver/mysql:
go get -u github.com/go-sql-driver/mysql
2.导入必要的包
导入database/sql和github.com/go-sql-driver/mysql包:
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
3.连接到数据库: 使用database/sql包的Open函数来连接到MySQL数据库:
func main() {
db, err := sql.Open("mysql", "user:password@tcp(hostname:port)/dbname")
if err != nil {
panic(err.Error())
}
defer db.Close()
// 确保数据库连接成功
err = db.Ping()
if err != nil {
panic(err.Error())
}
fmt.Println("数据库连接成功!")
}
也可以使用sqlx:
database, err := sqlx.Open("mysql", "root:XXXX@tcp(127.0.0.1:3306)/test")
数据库操作
举一个增删改查的例子:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
ID int
Name string
Age int
}
func main() {
// 连接到数据库
db, err := sql.Open("mysql", "user:password@tcp(hostname:port)/dbname")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 确保数据库连接成功
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("数据库连接成功!")
// 插入数据
result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "John Doe", 30)
if err != nil {
log.Fatal(err)
}
// 获取插入的ID
insertedID, err := result.LastInsertId()
if err != nil {
log.Fatal(err)
}
fmt.Printf("插入的ID为:%d\n", insertedID)
// 查询数据
rows, err := db.Query("SELECT id, name, age FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
fmt.Println("查询结果:")
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
// 更新数据
_, err = db.Exec("UPDATE users SET name=?, age=? WHERE id=?", "Bob", 35, insertedID)
if err != nil {
log.Fatal(err)
}
fmt.Println("数据更新成功!")
// 查询数据(确认更新结果)
rows, err = db.Query("SELECT id, name, age FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
fmt.Println("查询结果:")
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
// 删除数据
_, err = db.Exec("DELETE FROM users WHERE id=?", insertedID)
if err != nil {
log.Fatal(err)
}
fmt.Println("数据删除成功!")
// 查询数据(确认删除结果)
rows, err = db.Query("SELECT id, name, age FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
fmt.Println("查询结果:")
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
}
mysql事务特性: - 原子性 - 一致性 - 隔离性 - 持久性
golang mysql事务应用举例:
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
if err != nil {
tx.Rollback() // 出现错误,回滚事务
log.Fatal(err)
}
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
Db.Begin() 开始事务 Db.Commit() 提交事务 Db.Rollback() 回滚事务
这里使用db.Begin()来开始一个新的事务,并在其中执行插入数据和查询数据操作。如果任何一个操作失败,我们通过调用tx.Rollback()来回滚事务,否则,我们通过调用tx.Commit()来提交事务。这样可以保证数据库的一致性,即使在多个操作过程中出现错误也可以回滚到初始状态。
我们发现,这里还是需要自己编写sql语句,因为database/sql是Go语言的标准库,提供了一个通用的接口用于与各种数据库进行交互。它是一个轻量级的库,功能较为简单,主要用于执行SQL查询和事务。
如果想操作更方便执行更简单的话,可以是用gorm库,它构建在database/sql之上,提供了更高级的数据库操作功能。gorm可以将数据库表映射到Go语言的结构体,从而可以通过结构体来执行CRUD操作,而无需手动编写SQL语句。gorm支持事务、自动迁移、关联查询等高级功能,使得数据库操作更加方便和易于维护。也是go中最流行的ORM库之一。
使用步骤:
1.安装gorm库:
go get -u gorm.io/gorm
2.导入必要的包
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
3.连接到数据库
func main() {
dsn := "user:password@tcp(hostname:port)/dbname"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err.Error())
}
defer db.Close()
fmt.Println("数据库连接成功!")
}
4.定义模型结构体
type User struct {
gorm.Model
Name string
Age int
}
5.创建表映射和数据迁移
func main() {
// 执行数据迁移,将User结构体映射到数据库表
db.AutoMigrate(&User{})
}
以下是增删改查示例:
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
gorm.Model
Name string
Age int
}
func main() {
// 连接到数据库
dsn := "user:password@tcp(hostname:port)/dbname"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err.Error())
}
defer db.Close()
fmt.Println("数据库连接成功!")
// 创建表结构(数据迁移)
err = db.AutoMigrate(&User{})
if err != nil {
panic(err.Error())
}
// 插入数据
user := User{
Name: "John Doe",
Age: 30,
}
result := db.Create(&user)
if result.Error != nil {
panic(result.Error)
}
fmt.Println("插入的ID为:", user.ID)
// 查询数据
var users []User
db.Find(&users)
for _, user := range users {
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
// 更新数据
db.Model(&user).Update("Name", "Bob")
db.Model(&user).Update("Age", 35)
// 查询数据(确认更新结果)
db.Find(&users)
for _, user := range users {
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
// 删除数据
db.Delete(&user)
// 查询数据(确认删除结果)
db.Find(&users)
for _, user := range users {
fmt.Printf("ID: %d, Name: %s, Age: %d\n", user.ID, user.Name, user.Age)
}
}
基础的使用是没有问题的,如何灵活使用,为自己所用才是关键。