## 使用database/sql包操作MySQL 关系数据库较为常见且易于理解。MySQL和Postgres是两个最流行的开源关系数据库。本节将演示如何使用database/sql包,该包为许多关系数据库提供钩子并自动处理连接池、连接持续时间等。 该包的未来版本将提供包括对上下文和超时的支持。 ### 实践 1. 获取第三方库: ``` go get github.com/go-sql-driver/mysql ``` 2. 建立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 } ``` 3. 建立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 } ``` 4. 建立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() } ``` 5. 建立 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 } ``` 6. 建立 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) } } ``` 7. 这会输出: ``` 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环境变量中检索数据库用户名和密码的。 * * * * 学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。 Golang中国(211938256) beego实战(258969317) Go实践(386056972)