使用database/sql包操作MySQL
发布者:admin 发表于:417天前 阅读数:481 评论:0

关系数据库较为常见且易于理解。MySQL和Postgres是两个最流行的开源关系数据库。本节将演示如何使用database/sql包,该包为许多关系数据库提供钩子并自动处理连接池、连接持续时间等。

该包的未来版本将提供包括对上下文和超时的支持。

实践

获取第三方库:

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

建立config.go:

package database

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

    _ "github.com/go-sql-driver/mysql" //注意这里的导入方式
)

// Example 保存了查询的结果
type Example struct {
    Name    string
    Created *time.Time
}

// Setup 配置数据库连接
func Setup() (*sql.DB, error) {
    db, err := sql.Open("mysql", 
        fmt.Sprintf("%s:%s@/gocookbook?parseTime=true", os.Getenv("MYSQLUSERNAME"), os.Getenv("MYSQLPASSWORD")))
    if err != nil {
        return nil, err
    }
    return db, nil
}

建立create.go:

package database

import (
    "database/sql"

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

// Create 建立一个表并填充数据
func Create(db *sql.DB) error {

    if _, err := db.Exec("CREATE TABLE example (name VARCHAR(20), created DATETIME)"); err != nil {
        return err
    }

    if _, err := db.Exec(`INSERT INTO example (name, created) values ("Aaron", NOW())`); err != nil {
        return err
    }

    return nil
}

建立query.go:

package database

import (
    "database/sql"
    "fmt"

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

// Query 获取一个新的连接到数据库 并进行查询
func Query(db *sql.DB) error {
    name := "Aaron"
    rows, err := db.Query("SELECT name, created FROM example where name=?", name)
    if err != nil {
        return err
    }
    defer rows.Close()
    for rows.Next() {
        var e Example
        if err := rows.Scan(&e.Name, &e.Created); err != nil {
            return err
        }
        fmt.Printf("Results:\n\tName: %s\n\tCreated: %v\n", e.Name, e.Created)
    }
    return rows.Err()
}

建立 exec.go:

package database

import (
    "database/sql"

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

// Exec 删除该表
func Exec(db *sql.DB) error {
    // 在删除该表时存在未处理的错误 这样写并不推荐
    defer db.Exec("DROP TABLE example")

    if err := Create(db); err != nil {
        return err
    }

    if err := Query(db); err != nil {
        return err
    }
    return nil
}

建立 main.go:

package main

import (
    "github.com/agtorre/go-cookbook/chapter5/database"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := database.Setup()
    if err != nil {
        panic(err)
    }

    if err := database.Exec(db); err != nil {
        panic(err)
    }
}

这会输出:

Results:
    Name: Aaron
    Created: 2017-02-16 19:02:36 +0000 UTC

说明

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

该行引入了数据库驱动。如果要连接到Postgres,SQLite或任何其他实现了database/sql接口的驱动,命令将类似。

一旦建立连接成功,该包会建立连接池。你可以直接在连接上执行SQL,也可以创建用commit和rollback命令执行的事务对象。在随后的章节会进一步探讨连接池的相关问题。

在与数据库通信时,mysql包为Go的时间对象提供了一些便利支持。 注意本节是从从MYSQLUSERNAME和MYSQLPASSWORD环境变量中检索数据库用户名和密码的。