Files
build-web-application-with-…/zh-tw/05.2.md
2019-02-26 01:40:54 +08:00

142 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 5.2 使用MySQL資料庫
目前Internet上流行的網站構架方式是LAMP其中的M即MySQL, 作為資料庫MySQL以免費、開源、使用方便為優勢成為了很多Web開發的後端資料庫儲存引擎。
## MySQL驅動
Go中支援MySQL的驅動目前比較多有如下幾種有些是支援database/sql標準而有些是採用了自己的實現介面,常用的有如下幾種:
- https://github.com/go-sql-driver/mysql 支援database/sql全部採用go寫。
- https://github.com/ziutek/mymysql 支援database/sql也支援自訂的介面全部採用go寫。
- https://github.com/Philio/GoMySQL 不支援database/sql自訂介面全部採用go寫。
接下來的例子我主要以第一個驅動為例(我目前專案中也是採用它來驅動),也推薦大家採用它,主要理由:
- 這個驅動比較新,維護的比較好
- 完全支援database/sql介面
- 支援keepalive保持長連線,雖然[星星](http://www.mikespook.com)fork的mymysql也支援keepalive但不是執行緒安全的這個從底層就支援了keepalive。
## 示例程式碼
接下來的幾個小節裡面我們都將採用同一個資料庫表結構資料庫test使用者表userinfo關聯使用者資訊表userdetail。
```sql
CREATE TABLE `userinfo` (
`uid` INT(10) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(64) NULL DEFAULT NULL,
`department` VARCHAR(64) NULL DEFAULT NULL,
`created` DATE NULL DEFAULT NULL,
PRIMARY KEY (`uid`)
);
CREATE TABLE `userdetail` (
`uid` INT(10) NOT NULL DEFAULT '0',
`intro` TEXT NULL,
`profile` TEXT NULL,
PRIMARY KEY (`uid`)
)
```
如下示例將示範如何使用database/sql介面對資料庫表進行增刪改查操作
```Go
package main
import (
"database/sql"
"fmt"
//"time"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8")
checkErr(err)
//插入資料
stmt, err := db.Prepare("INSERT userinfo SET username=?,department=?,created=?")
checkErr(err)
res, err := stmt.Exec("astaxie", "研發部門", "2012-12-09")
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
//更新資料
stmt, err = db.Prepare("update userinfo set username=? where uid=?")
checkErr(err)
res, err = stmt.Exec("astaxieupdate", id)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
//查詢資料
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
//刪除資料
stmt, err = db.Prepare("delete from userinfo where uid=?")
checkErr(err)
res, err = stmt.Exec(id)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
db.Close()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
```
透過上面的程式碼我們可以看出Go操作Mysql資料庫是很方便的。
關鍵的幾個函式我解釋一下:
sql.Open()函式用來開啟一個註冊過的資料庫驅動go-sql-driver中註冊了mysql這個資料庫驅動第二個引數是DSN(Data Source Name)它是go-sql-driver定義的一些資料庫連結和配置資訊。它支援如下格式
user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname
db.Prepare()函式用來返回準備要執行的sql操作然後返回準備完畢的執行狀態。
db.Query()函式用來直接執行Sql返回Rows結果。
stmt.Exec()函式用來執行stmt準備好的SQL語句
我們可以看到我們傳入的引數都是=?對應的資料這樣做的方式可以一定程度上防止SQL注入。
## links
* [目錄](<preface.md>)
* 上一節: [database/sql介面](<05.1.md>)
* 下一節: [使用SQLite資料庫](<05.3.md>)