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)
    }
}

基础的使用是没有问题的,如何灵活使用,为自己所用才是关键。