美文网首页
四、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数据库

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