美文网首页
四、GO Web编程示例 - MySQL数据库

四、GO Web编程示例 - MySQL数据库

作者: coutinho | 来源:发表于2020-06-29 23:05 被阅读0次

简介

此示例将研究GO语言中MySQL数据库访问的基础知识,创建数据库表,存储和读取数据。

安装go-sql-driver / mysql软件包

Go编程语言附带了一个名为database / sql的软件包,用于查询各种SQL数据库。 这很有用,因为它将所有通用SQL功能抽象为一个API供你使用,但 Go不包括数据库驱动程序。 在Go中,数据库驱动程序是一个用于实现特定数据库底层细节的软件包(本例为MySQL)。由于无法预见哪些数据库将来都会投入使用,而支持每个可能的数据库将需要大量维护工作,因此Go语言未包含数据库驱动程序,需要额外进行安装。
要安装MySQL数据库驱动程序,只需要在终端中执行以下操作:

go get -u github.com/go-sql-driver/mysql

连接到MySQL数据库

安装所有必需的软件包后,需要检查的第一件事是,是否可以成功连接到MySQL数据库。 如果尚未运行MySQL数据库服务器,可以通过Docker轻松的启动一个实例。 这是MySQL的映像的官方Docker镜像:https://hub.docker.com/_/mysql
要检查是否可以连接到数据库,请导入数据库/ sql和go-sql-driver / mysql软件包,并按如下所示打开连接:

import "database/sql"
import _ "go-sql-driver/mysql"



// Configure the database connection (always check errors)
db, err := sql.Open("mysql", "username:password@(127.0.0.1:3306)/dbname?parseTime=true")


// Initialize the first connection to the database, to see if everything works correctly.
// Make sure to check the error.
err := db.Ping()

创建第一个数据库表

我们数据库中的每个数据条目都存储在一个特定的表中。 数据库表由列和行组成。 这些列为每个数据条目提供一个标签并指定其类型。 这些行是插入的数据值。 在我们的第一个示例中,我们想要创建一个像这样的表:

id username password created_at
1 johndoe secret 2019-08-10 12:30:00

创建表格的SQL命令如下:

CREATE TABLE users (
    id INT AUTO_INCREMENT,
    username TEXT NOT NULL,
    password TEXT NOT NULL,
    created_at DATETIME,
    PRIMARY KEY (id)
);

现在有了SQL命令,可以使用database/sql包在MySQL数据库中创建表:

query := `
    CREATE TABLE users (
        id INT AUTO_INCREMENT,
        username TEXT NOT NULL,
        password TEXT NOT NULL,
        created_at DATETIME,
        PRIMARY KEY (id)
    );`

// Executes the SQL query in our database. Check err to ensure there was no error.
_, err := db.Exec(query)

插入第一个用户

如果你熟悉SQL,向表中插入新数据就像创建表一样容易。 需要注意的一件事是:默认情况下,Go使用准备好的语句将动态数据插入SQL查询语句中,这是一种将用户提供的数据安全地传递到数据库的方式,而不会造成任何损坏。 在Web编程的早期,程序员将带有查询的数据直接传递到数据库,这导致了巨大的漏洞,并可能破坏整个Web应用程序,请不要那样做。
要将第一个用户插入数据库表,创建一个如下的SQL查询。此处省略了id列,因为它是由MySQL自动设置的。 问号告诉SQL驱动程序,它们是实际数据的占位符。 在这里可以看到准备好的语句。

INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)

现在可以在Go中使用此语句插入用户。

import "time"

username := "johndoe"
password := "secret"
createdAt := time.Now()

// Inserts our data into the users table and returns with the result and a possible error.
// The result contains information about the last inserted id (which was auto-generated for us) and the count of rows this query affected.
result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, username, password, createdAt)

要获取用户在数据库中最新创建的ID,只需按以下方式获取:

userID, err := result.LastInsertId()

查询用户表

现在表中有一个用户,我们想查询它并获取其所有信息。 在Go中有两种查询表的方法。 db.Query可以迭代查询多行;还有db.QueryRow只查询特定的行。
查询特定行的工作原理基本上与之前介绍的所有其他SQL命令一样。
SQL命令通过其ID查询单个用户,如下所示:

SELECT id, username, password, created_at FROM users WHERE id = ?

在Go中首先声明一些变量来存储数据,然后查询单个数据库行,如下所示:

var (
    id        int
    username  string
    password  string
    createdAt time.Time
)

// Query the database and scan the values into out variables. Don't forget to check for errors.
query := `SELECT id, username, password, created_at FROM users WHERE id = ?`
err := db.QueryRow(query, 1).Scan(&id, &username, &password, &createdAt)

查询所有用户

前面的部分介绍了如何查询单个用户行。 而许多应用程序都有查询所有用户的应用。 这与上面的示例相似,只是涉及更多的编码。
我们可以使用上面示例中的SQL命令并修改WHERE子句。 这样可以查询所有用户。

SELECT id, username, password, created_at FROM users

在Go中首先声明一些变量来存储数据,然后查询单个数据库行,如下所示:

type user struct {
  id        int
  username  string
  password  string
  createdAt time.Time
}

rows, err := db.Query(`SELECT id, username, password, created_at FROM users`) // check err
defer rows.Close()

var users []user
for rows.Next() {
  var u user
  err := rows.Scan(&u.id, &u.username, &u.password, &u.createdAt) // check err
  users = append(users, u)
}
err := rows.Err() // check err

user切片现在包含的内容如下:

users {
    user {
        id:        1,
        username:  "johndoe",
        password:  "secret",
        createdAt: time.Time{wall: 0x0, ext: 63701044325, loc: (*time.Location)(nil)},
    },
    user {
        id:        2,
        username:  "alice",
        password:  "bob",
        createdAt: time.Time{wall: 0x0, ext: 63701044622, loc: (*time.Location)(nil)},
    },
}

删除用户

最后,从表中删除用户与上述各节中的.Exec一样简单:

_, err := db.Exec(`DELETE FROM users WHERE id = ?`, 1) // check err

代码

package main

import (
    "database/sql"
    "fmt"
    "log"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "root:root@(127.0.0.1:3306)/root?parseTime=true")
    if err != nil {
        log.Fatal(err)
    }
    if err := db.Ping(); err != nil {
        log.Fatal(err)
    }

    { // Create a new table
        query := `
            CREATE TABLE users (
                id INT AUTO_INCREMENT,
                username TEXT NOT NULL,
                password TEXT NOT NULL,
                created_at DATETIME,
                PRIMARY KEY (id)
            );`

        if _, err := db.Exec(query); err != nil {
            log.Fatal(err)
        }
    }

    { // Insert a new user
        username := "johndoe"
        password := "secret"
        createdAt := time.Now()

        result, err := db.Exec(`INSERT INTO users (username, password, created_at) VALUES (?, ?, ?)`, username, password, createdAt)
        if err != nil {
            log.Fatal(err)
        }

        id, err := result.LastInsertId()
        fmt.Println(id)
    }

    { // Query a single user
        var (
            id        int
            username  string
            password  string
            createdAt time.Time
        )

        query := "SELECT id, username, password, created_at FROM users WHERE id = ?"
        if err := db.QueryRow(query, 1).Scan(&id, &username, &password, &createdAt); err != nil {
            log.Fatal(err)
        }

        fmt.Println(id, username, password, createdAt)
    }

    { // Query all users
        type user struct {
            id        int
            username  string
            password  string
            createdAt time.Time
        }

        rows, err := db.Query(`SELECT id, username, password, created_at FROM users`)
        if err != nil {
            log.Fatal(err)
        }
        defer rows.Close()

        var users []user
        for rows.Next() {
            var u user

            err := rows.Scan(&u.id, &u.username, &u.password, &u.createdAt)
            if err != nil {
                log.Fatal(err)
            }
            users = append(users, u)
        }
        if err := rows.Err(); err != nil {
            log.Fatal(err)
        }

        fmt.Printf("%#v", users)
    }

    {
        _, err := db.Exec(`DELETE FROM users WHERE id = ?`, 1)
        if err != nil {
            log.Fatal(err)
        }
    }
}

相关文章

  • 四、GO Web编程示例 - MySQL数据库

    简介 此示例将研究GO语言中MySQL数据库访问的基础知识,创建数据库表,存储和读取数据。 安装go-sql-dr...

  • Go操作MySQL

    Go语言操作MySQL MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库。 Go操作...

  • Go操作MySQL

    MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库。 Go操作MySQL 连接 Go语...

  • MySQL数据实时增量同步到Elasticsearch

    一、go-mysql-transfer go-mysql-transfer是使用Go语言实现的MySQL数据库实时...

  • MySQL数据实时增量同步到Redis

    一、go-mysql-transfer go-mysql-transfer是使用Go语言实现的MySQL数据库实时...

  • MySQL数据实时增量同步到MongoDB

    一、go-mysql-transfer go-mysql-transfer是使用Go语言实现的MySQL数据库实时...

  • PHP全栈学习笔记23

    php,基础,流程控制,函数,字符串,数组,web交互,mysql数据库,PHP数据库编程,cookie与sess...

  • PHP全栈学习笔记23

    php,基础,流程控制,函数,字符串,数组,web交互,mysql数据库,PHP数据库编程,cookie与sess...

  • 3.1 Go操作MySQL数据库

    3.1 Go操作MySQL数据库 安装go操作MySQL的驱动go get -u -v github.com/go...

  • Go web编程

    Go web编程 专栏简介 分享 Go web 编程。在这里你可以了解到什么是 Go,为什么越来越多人喜欢它。在实...

网友评论

      本文标题:四、GO Web编程示例 - MySQL数据库

      本文链接:https://www.haomeiwen.com/subject/pcqwfktx.html