使用MySQL数据库
目前 Internet 上流行的网站构架方式是 LAMP/LNMP,其中的 M 即 MySQL, 作为数据库,MySQL 以免费、开源、使用方便为优势成为了很多Web开发的后端数据库存储引擎。

十余年的南宁网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销的优势是能够根据用户设备显示端的尺寸不同,自动调整南宁建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“南宁网站设计”,“南宁网站推广”以来,每个客户项目都认真落实执行。
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,保持长连接。 
接下来的几个小节里面我们都将采用同一个数据库表结构:数据库test,用户表userinfo,关联用户信息表userdetail。
 1
CREATE
 
TABLE
 
`userinfo`
 (
 2
    
`uid`
 
INT
(
10
) 
NOT
 
NULL
 AUTO_INCREMENT,
 3
    
`username`
 
VARCHAR
(
64
) 
NULL
 
DEFAULT
 
NULL
,
 4
    
`departname`
 
VARCHAR
(
64
) 
NULL
 
DEFAULT
 
NULL
,
 5
    
`created`
 
DATE
 
NULL
 
DEFAULT
 
NULL
,
 6
    PRIMARY 
KEY
 (
`uid`
)
 7
);
 8
 9
CREATE
 
TABLE
 
`userdetail`
 (
10
    
`uid`
 
INT
(
10
) 
NOT
 
NULL
 
DEFAULT
 
'0'
,
11
    
`intro`
 
TEXT
 
NULL
,
12
    
`profile`
 
TEXT
 
NULL
,
13
    PRIMARY 
KEY
 (
`uid`
)
14
)
如下示例将示范如何使用database/sql接口对数据库表进行增删改查操作:
 1
// 示例代码11-15
 2
package
 main
 3
 4
import
 (
 5
    
"database/sql"
 6
    
"fmt"
 7
    
//"time"
 8
 9
    _ 
"github.com/go-sql-driver/mysql"
10
)
11
12
func
 
main
()
 {
13
    db, err := sql.Open(
"mysql"
, 
"zuolan:zuolan@/test?charset=utf8"
)
14
    checkErr(err)
15
16
    
//插入数据
17
    stmt, err := db.Prepare(
"INSERT userinfo SET username=?,departname=?,created=?"
)
18
    checkErr(err)
19
20
    res, err := stmt.Exec(
"张三"
, 
"研发部门"
, 
"2017-09-09"
)
21
    checkErr(err)
22
23
    id, err := res.LastInsertId()
24
    checkErr(err)
25
26
    fmt.Println(id)
27
    
//更新数据
28
    stmt, err = db.Prepare(
"update userinfo set username=? where uid=?"
)
29
    checkErr(err)
30
31
    res, err = stmt.Exec(
"zuolanupdate"
, id)
32
    checkErr(err)
33
34
    affect, err := res.RowsAffected()
35
    checkErr(err)
36
37
    fmt.Println(affect)
38
39
    
//查询数据
40
    rows, err := db.Query(
"SELECT * FROM userinfo"
)
41
    checkErr(err)
42
43
    
for
 rows.Next() {
44
        
var
 uid 
int
45
        
var
 username 
string
46
        
var
 department 
string
47
        
var
 created 
string
48
        err = rows.Scan(&uid, &username, &department, &created)
49
        checkErr(err)
50
        fmt.Println(uid)
51
        fmt.Println(username)
52
        fmt.Println(department)
53
        fmt.Println(created)
54
    }
55
56
    
//删除数据
57
    stmt, err = db.Prepare(
"delete from userinfo where uid=?"
)
58
    checkErr(err)
59
60
    res, err = stmt.Exec(id)
61
    checkErr(err)
62
63
    affect, err = res.RowsAffected()
64
    checkErr(err)
65
66
    fmt.Println(affect)
67
68
    db.Close()
69
70
}
71
72
func
 
checkErr
(err error)
 {
73
    
if
 err != 
nil
 {
74
        
panic
(err)
75
    }
76
}
通过上面的代码我们可以看出,Go操作MySQL数据库是很方便的。
sql.Open()函数用来打开一个注册过的数据库驱动,go-sql-driver中注册了mysql这个数据库驱动,第二个参数是DSN(Data Source Name),它是go-sql-driver定义的一些数据库链接和配置信息。它支持如下格式:
1
user
@
unix
(/
path
/
to
/
socket
)/
dbname
?
charset
=
utf8
2
user:password@tcp(localhost:
5555
)/dbname?charset=utf8
3
user:password@/dbname
4
user:password@tcp([de:ad:be:ef::ca:fe]:
80
)/dbname
db.Prepare()函数用来返回准备要执行的sql操作,然后返回准备完毕的执行状态。
db.Query()函数用来直接执行Sql返回Rows结果。
stmt.Exec()函数用来执行stmt准备好的SQL语句
我们可以看到我们传入的参数都是=?对应的数据,这样做的方式可以一定程度上防止SQL注入。
使用SQLite数据库
SQLite是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。其特点是高度便携、使用方便、结构紧凑、高效、可靠。与其他数据库管理系统不同,SQLite的安装和运行非常简单,在大多数情况下,只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。
如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。SQLite可以是说开源的Access。
Go支持sqlite的驱动也比较多,但是很多都不支持database/sql接口:
- https://github.com/mattn/go-sqlite3 支持database/sql接口,基于cgo(关于cgo的知识请参看官方文档)。 
- https://github.com/feyeleanor/gosqlite3 不支持database/sql接口,基于cgo。 
- https://github.com/phf/go-sqlite3 不支持database/sql接口,基于cgo。 
目前支持database/sql的SQLite数据库驱动比较少,采用标准接口有利于以后出现更好的驱动的时候做迁移,因此本节后面都采用第一个驱动。
示例的数据库表结构如下所示,相应的建表SQL:
 1
CREATE
 
TABLE
 
`userinfo`
 (
 2
    
`uid`
 
INTEGER
 PRIMARY 
KEY
 AUTOINCREMENT,
 3
    
`username`
 
VARCHAR
(
64
) 
NULL
,
 4
    
`departname`
 
VARCHAR
(
64
) 
NULL
,
 5
    
`created`
 
DATE
 
NULL
 6
);
 7
 8
CREATE
 
TABLE
 
`userdeatail`
 (
 9
    
`uid`
 
INT
(
10
) 
NULL
,
10
    
`intro`
 
TEXT
 
NULL
,
11
    
`profile`
 
TEXT
 
NULL
,
12
    PRIMARY 
KEY
 (
`uid`
)
13
);
看下面Go程序是如何操作数据库表,进行数据增删改查的:
 1
// 示例代码11-16
 2
package
 main
 3
 4
import
 (
 5
    
"database/sql"
 6
    
"fmt"
 7
    
"time"
 8
 9
    _ 
"github.com/mattn/go-sqlite3"
10
)
11
12
func
 
main
()
 {
13
    db, err := sql.Open(
"sqlite3"
, 
"./demo.db"
)
14
    checkErr(err)
15
16
    
//插入数据
17
    stmt, err := db.Prepare(
"INSERT INTO userinfo(username, departname, created) values(?,?,?)"
)
18
    checkErr(err)
19
20
    res, err := stmt.Exec(
"张三"
, 
"研发部门"
, 
"2017-09-09"
)
21
    checkErr(err)
22
23
    id, err := res.LastInsertId()
24
    checkErr(err)
25
26
    fmt.Println(id)
27
    
//更新数据
28
    stmt, err = db.Prepare(
"update userinfo set username=? where uid=?"
)
29
    checkErr(err)
30
31
    res, err = stmt.Exec(
"zuolanupdate"
, id)
32
    checkErr(err)
33
34
    affect, err := res.RowsAffected()
35
    checkErr(err)
36
37
    fmt.Println(affect)
38
39
    
//查询数据
40
    rows, err := db.Query(
"SELECT * FROM userinfo"
)
41
    checkErr(err)
42
43
    
for
 rows.Next() {
44
        
var
 uid 
int
45
        
var
 username 
string
46
        
var
 department 
string
47
        
var
 created time.Time
48
        err = rows.Scan(&uid, &username, &department, &created)
49
        checkErr(err)
50
        fmt.Println(uid)
51
        fmt.Println(username)
52
        fmt.Println(department)
53
        fmt.Println(created)
54
    }
55
56
    
//删除数据
57
    stmt, err = db.Prepare(
"delete from userinfo where uid=?"
)
58
    checkErr(err)
59
60
    res, err = stmt.Exec(id)
61
    checkErr(err)
62
63
    affect, err = res.RowsAffected()
64
    checkErr(err)
65
66
    fmt.Println(affect)
67
68
    db.Close()
69
70
}
71
72
func
 
checkErr
(err error)
 {
73
    
if
 err != 
nil
 {
74
        
panic
(err)
75
    }
76
}
我们可以看到上面的代码和MySQL例子里面的代码几乎是一模一样的,唯一改变的就是导入的驱动改变了,然后调用sql.Open是采用了SQLite的方式打开。
使用PostgreSQL数据库
PostgreSQL是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的BSD风格许可证下发行。它提供了相对其他开放源代码数据库系统(比如MySQL和Firebird),和对专有系统比如Oracle、Sybase、IBM的DB2和Microsoft SQL Server的一种选择。
PostgreSQL和MySQL比较,它更加庞大一点,因为它是用来替代Oracle而设计的。所以在企业应用中采用PostgreSQL是一个明智的选择。
MySQL被Oracle收购之后正在逐步的封闭(自MySQL 5.5.31以后的所有版本将不再遵循GPL协议),鉴于此,将来我们也许会选择PostgreSQL而不是MySQL作为项目的后端数据库。
Go实现的支持PostgreSQL的驱动也很多,因为国外很多人在开发中使用了这个数据库。
- https://github.com/lib/pq 支持database/sql驱动,纯Go写的; 
- https://github.com/jbarham/gopgsqldriver 支持database/sql驱动,纯Go写的; 
- https://github.com/lxn/go-pgsql 支持database/sql驱动,纯Go写的。 
在下面的示例中采用第一个驱动,因为它目前使用的人最多,在Github上也比较活跃。
数据库建表语句:
 1
CREATE
 
TABLE
 userinfo
 2
(
 3
    uid 
serial
 
NOT
 
NULL
,
 4
    username 
character
 
varying
(
100
) 
NOT
 
NULL
,
 5
    departname 
character
 
varying
(
500
) 
NOT
 
NULL
,
 6
    Created 
date
,
 7
    
CONSTRAINT
 userinfo_pkey PRIMARY 
KEY
 (uid)
 8
)
 9
WITH
 (OIDS=
FALSE
);
10
11
CREATE
 
TABLE
 userdeatail
12
(
13
    uid 
integer
,
14
    intro 
character
 
varying
(
100
),
15
    profile 
character
 
varying
(
100
)
16
)
17
WITH
(OIDS=
FALSE
);
看下面这个Go如何操作数据库表,进行数据的增删改查:
 1
// 示例代码11-17
 2
package
 main
 3
 4
import
 (
 5
    
"database/sql"
 6
    
"fmt"
 7
 8
    _ 
"github.com/lib/pq"
 9
)
10
11
func
 
main
()
 {
12
    db, err := sql.Open(
"postgres"
, 
"user=zuolan password=zuolan dbname=test sslmode=disable"
)
13
    checkErr(err)
14
15
    
//插入数据
16
    stmt, err := db.Prepare(
"INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) RETURNING uid"
)
17
    checkErr(err)
18
19
    res, err := stmt.Exec(
"张三"
, 
"研发部门"
, 
"2017-09-09"
)
20
    checkErr(err)
21
22
    
// pg不支持这个函数,因为他没有类似MySQL的自增ID
23
    
// id, err := res.LastInsertId()
24
    
// checkErr(err)
25
    
// fmt.Println(id)
26
27
    
var
 lastInsertId 
int
28
    err = db.QueryRow(
"INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;"
, 
"zuolan"
, 
"研发部门"
, 
"2017-09-09"
).Scan(&lastInsertId)
29
    checkErr(err)
30
    fmt.Println(
"最后插入id ="
, lastInsertId)
31
32
33
    
//更新数据
34
    stmt, err = db.Prepare(
"update userinfo set username=$1 where uid=$2"
)
35
    checkErr(err)
36
37
    res, err = stmt.Exec(
"zuolanupdate"
, 
1
)
38
    checkErr(err)
39
40
    affect, err := res.RowsAffected()
41
    checkErr(err)
42
43
    fmt.Println(affect)
44
45
    
//查询数据
46
    rows, err := db.Query(
"SELECT * FROM userinfo"
)
47
    checkErr(err)
48
49
    
for
 rows.Next() {
50
        
var
 uid 
int
51
        
var
 username 
string
52
        
var
 department 
string
53
        
var
 created 
string
54
        err = rows.Scan(&uid, &username, &department, &created)
55
        checkErr(err)
56
        fmt.Println(uid)
57
        fmt.Println(username)
58
        fmt.Println(department)
59
        fmt.Println(created)
60
    }
61
62
    
//删除数据
63
    stmt, err = db.Prepare(
"delete from userinfo where uid=$1"
)
64
    checkErr(err)
65
66
    res, err = stmt.Exec(
1
)
67
    checkErr(err)
68
69
    affect, err = res.RowsAffected()
70
    checkErr(err)
71
72
    fmt.Println(affect)
73
74
    db.Close()
75
76
}
77
78
func
 
checkErr
(err error)
 {
79
    
if
 err != 
nil
 {
80
        
panic
(err)
81
    }
82
}
从上面的代码我们可以看到,PostgreSQL是通过 1, 2这种方式来指定要传递的参数,而不是MySQL中的?,另外在sql.Open中的dsn信息的格式也与MySQL的驱动中的dsn格式不一样,所以在使用时请注意它们的差异。
还有pg不支持LastInsertId函数,因为PostgreSQL内部没有实现类似MySQL的自增ID返回,其他的代码几乎是一模一样。
NoSql数据库操作
NOSQL(Not Only SQL),指的是非关系型的数据库。随着Web2.0的兴起,传统的关系数据库在应付Web2.0网站,特别是超大规模和高并发的SNS类型的Web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。
而Go语言作为21世纪的C语言,对NOSQL的支持也是很好,目前流行的NOSQL主要有redis、MongoDB、Cassandra和Membase等。这些数据库都有高性能、高并发读写等特点,目前已经广泛应用于各种应用中。
1. Redis
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。
目前应用redis最广泛的应该是新浪微博平台,其次还有Facebook收购的图片社交网站instagram。Go目前支持redis的驱动有如下:
- https://github.com/garyburd/redigo 
- https://github.com/go-redis/redis 
- https://github.com/hoisie/redis 
- https://github.com/alphazero/Go-Redis 
- https://github.com/simonz05/godis 
推荐使用第一个,用法上和上面驱动没有太大区别,限于篇幅不再展开。
2. mongoDB
MongoDB是一个高性能,开源,无模式的文档型数据库,是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,采用的是类似json的bjson格式来存储数据,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
目前Go支持mongoDB最好的驱动就是mgo(http://labix.org/mgo),这个驱动目前最有可能成为官方的pkg。安装mgo的命令为:
1go get gopkg.in/mgo.v2
分享标题:Go语言如何操作常见的数据库
文章分享:http://www.scyingshan.cn/article/gjejhi.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 