|
1 | 1 | #5.2使用MySQL数据库 |
| 2 | +目前Internet上流行的网站构架方式是LAMP,MySQL数据库是其中的标配之一,MySQL作为数据库,它是免费的、开源的、而且使用起来非常的方便。所以目前很多的Web开发都采用MySQL作为后端的数据库存储。 |
| 3 | + |
| 4 | +##MySQL驱动 |
| 5 | +Go中支持MySQL的驱动目前比较多,有如下几种,有些是支持database/sql标准,而有些是采用了自己的实现接口。 |
| 6 | + |
| 7 | +- http://code.google.com/p/go-mysql-driver/ 支持database/sql,全部采用go写。 |
| 8 | +- https://github.com/ziutek/mymysql 支持database/sql,也支持自定义的接口,全部采用go写。 |
| 9 | +- https://github.com/Philio/GoMySQL 不支持database/sql,自定义接口,全部采用go写。 |
| 10 | + |
| 11 | +上面三个数据库驱动是目前使用率最高的库,我接下来的例子主要采用第一个为主(我目前项目中也是采用第一个驱动来写),也推荐大家采用第一个驱动,主要理由: |
| 12 | + |
| 13 | +- 目前这个驱动比较新,维护的比较好 |
| 14 | +- 完全支持database/sql接口 |
| 15 | +- 支持keepalive,保持长连接,虽然星星fork了mymysql也支持keepalive,但是不是线程安全的,这个从底层就支持了keepalive。 |
| 16 | + |
| 17 | +##示例代码 |
| 18 | +接下来的几个小节里面我们都采用同一个数据库表结构,我们新建一个数据库test,新建用户表userinfo,关联用户信息表userdetail。 |
| 19 | + |
| 20 | +CREATE TABLE `userinfo` ( |
| 21 | +`uid` INT(10) NOT NULL AUTO_INCREMENT, |
| 22 | +`username` VARCHAR(64) NULL DEFAULT NULL, |
| 23 | +`departname` VARCHAR(64) NULL DEFAULT NULL, |
| 24 | +`created` DATE NULL DEFAULT NULL, |
| 25 | +PRIMARY KEY (`uid`) |
| 26 | +) |
| 27 | + |
| 28 | +CREATE TABLE `userdetail` ( |
| 29 | +`uid` INT(10) NOT NULL DEFAULT '0', |
| 30 | +`intro` TEXT NULL, |
| 31 | +`profile` TEXT NULL, |
| 32 | +PRIMARY KEY (`uid`) |
| 33 | +) |
| 34 | + |
| 35 | +看下面这个Go如何操作数据库表数据:增删改查 |
| 36 | + |
| 37 | +package main |
| 38 | + |
| 39 | +import ( |
| 40 | +_ "code.google.com/p/go-mysql-driver/mysql" |
| 41 | +"database/sql" |
| 42 | +"fmt" |
| 43 | +//"time" |
| 44 | +) |
| 45 | + |
| 46 | +func main() { |
| 47 | +db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8") |
| 48 | +checkErr(err) |
| 49 | + |
| 50 | +//插入数据 |
| 51 | +stmt, errs := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") |
| 52 | +checkErr(errs) |
| 53 | + |
| 54 | +res, errres := stmt.Exec("astaxie", "研发部门", "2012-12-09") |
| 55 | +checkErr(errres) |
| 56 | + |
| 57 | +id, errid := res.LastInsertId() |
| 58 | +checkErr(errid) |
| 59 | + |
| 60 | +fmt.Println(id) |
| 61 | +//更新数据 |
| 62 | +stmt, errs = db.Prepare("update userinfo set username=? where uid=?") |
| 63 | +checkErr(errs) |
| 64 | + |
| 65 | +res, errres = stmt.Exec("astaxieupdate", id) |
| 66 | +checkErr(errres) |
| 67 | + |
| 68 | +affect, erraff := res.RowsAffected() |
| 69 | +checkErr(erraff) |
| 70 | + |
| 71 | +fmt.Println(affect) |
| 72 | + |
| 73 | +//查询数据 |
| 74 | +rows, errrow := db.Query("SELECT * FROM userinfo") |
| 75 | +checkErr(errrow) |
| 76 | + |
| 77 | +for rows.Next() { |
| 78 | +var uid int |
| 79 | +var username string |
| 80 | +var department string |
| 81 | +var created string |
| 82 | +err = rows.Scan(&uid, &username, &department, &created) |
| 83 | +checkErr(err) |
| 84 | +fmt.Println(uid) |
| 85 | +fmt.Println(username) |
| 86 | +fmt.Println(department) |
| 87 | +fmt.Println(created) |
| 88 | +} |
| 89 | + |
| 90 | +//删除数据 |
| 91 | +stmt, errrow = db.Prepare("delete from userinfo where uid=?") |
| 92 | +checkErr(errrow) |
| 93 | + |
| 94 | +res, errres = stmt.Exec(id) |
| 95 | +checkErr(errres) |
| 96 | + |
| 97 | +affect, erraff = res.RowsAffected() |
| 98 | +checkErr(erraff) |
| 99 | + |
| 100 | +fmt.Println(affect) |
| 101 | + |
| 102 | +} |
| 103 | + |
| 104 | +func checkErr(err error) { |
| 105 | +if err != nil { |
| 106 | +panic(err) |
| 107 | +} |
| 108 | +} |
| 109 | + |
| 110 | +通过上面的代码我们可以看出,Go操作Mysql数据库是很方便的。 |
| 111 | + |
| 112 | +关键的几个函数我解释一下: |
| 113 | + |
| 114 | +sql.Open()函数用来打开一个注册过的数据库驱动,go-mysql-driver中注册了mysql这个数据库驱动,第二个参数是DNS(Data Source Name),它是go-mysql-drivev定义的一些数据库链接和配置信息。它支持如下格式: |
| 115 | + |
| 116 | +user@unix(/path/to/socket)/dbname?charset=utf8 |
| 117 | +user:password@tcp(localhost:5555)/dbname?charset=utf8&keepalive=1 |
| 118 | +user:password@/dbname |
| 119 | +user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname |
| 120 | + |
| 121 | +db.Prepare()函数用来返回准备要执行的sql操作,然后返回准备完毕的执行状态。 |
| 122 | + |
| 123 | +db.Query()函数用来直接执行Sql返回Rows结果。 |
| 124 | + |
| 125 | +stmt.Exec()函数用来执行stmt准备好的SQL语句 |
| 126 | + |
| 127 | +我们可以看到我们传入的参数都是=?对应的数据,这样做的方式可以一定程度上防止SQL注入。 |
| 128 | + |
2 | 129 |
|
3 | 130 |
|
4 | 131 | ## links |
|
0 commit comments