这是我参加第五届青训营伴学笔记创作活动的第二天.
go-mysql-driver是什么?
一个针对go的database/sql包的mysql驱动.
有什么特点?
- 速度快并且轻量.
- 基于原生go实现,没有使用c-bindings.
- 能够基于多种协议建立连接(TCP/IPV4, TCP/IPV6等).
- 支持占位符.
- 支持自动连接池.
- ...
如何使用它?(基本使用)
- 首先安装go-sql-driver/mysql驱动
$ go get -u github.com/go-sql-driver/mysql
- 以副作用形式加载mysql驱动包就可以开始使用了.
- 编写相关代码
import (
"database/sql"
"time"
_ "github.com/go-sql-driver/mysql"
)
func main(){
db,err :=sql.Open("mysql","用户名:密码@/数据库名称?一些你想加的参数")
defer db.Close()
err = db.Ping()
if err != nil {
// do something here
}
}
需要注意的是,sql.Open仅仅建立了与数据库通信的抽象,同时他不会检查输入的参数是否正确,真正的连接会延迟到程序第一次执行命令(增删改查等)才会建立.
所以mysql包贴心地提供了Ping函数,来检查能正确连接数据库,
从数据库中获取数据
- 使用db.Query语句
var (
id int
name string
)
rows, err := db.Query("select id, name from users where id = ?", 1)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
log.Println(id, name)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
直接使用db.Query进行查询的话可能会存在安全问题,比如看以下代码:
...
rows, err := db.Query("select id, name from users where id = ?", "1 or 1=1")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
log.Println(id, name)
}
...
这么做的话直接寄了.
go-sql-driver/mysql贴心地提供了prepared statements哈哈哈.
stmt, err := db.Prepare("select id, name from users where id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
// ...
}
if err = rows.Err(); err != nil {
log.Fatal(err)
}
跟java的mybatis类似(至于为什么不举其他例子,因为我只知道个mybatis有..),通过预编译手段以及使用?占位符能有效防止sql注入.
stmt, err := db.Prepare("select id, name from users where id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
// ...
}
if err = rows.Err(); err != nil {
log.Fatal(err)
}
修改数据集最好使用db.Exec进行修改,千万别用db.Query执行修改.因为Query函数要求返回结果集,
这个结果集对应的sql连接在使用结果后需要关闭,如果用Query执行修改语句会导致该连接一直无法得到关闭.
至于事务这种高级特性以及相关用法还是等你自己进行探索吧.