From ae3942d8ac46abf26eb8ff630371edc76ecbf32a Mon Sep 17 00:00:00 2001 From: astaxie Date: Tue, 11 Sep 2012 17:35:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=94=AF=E6=8C=81sqlite=E5=92=8Cpg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 5.3.md | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5.4.md | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) diff --git a/5.3.md b/5.3.md index 88b9ace..62fe113 100644 --- a/5.3.md +++ b/5.3.md @@ -1,5 +1,114 @@ #5.3使用SQLite数据库 +SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。其特点是高度便携、使用方便、结构紧凑、高效、可靠。 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下,只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。SQLite可以是说开源的Access。 + +##驱动 +Go支持sqlite的驱动也比较多,但是好多都是不支持database/sql接口的 + +-https://github.com/mattn/go-sqlite3 支持database/sql接口,基于cgo写的 +-https://github.com/feyeleanor/gosqlite3 不支持database/sql接口,基于cgo写的 +-https://github.com/phf/go-sqlite3 不支持database/sql接口,基于cgo写的 + +我们看到目前支持database/sql的SQLite数据库驱动只有第一个,我目前采用的也是第一个驱动进行开发的。采用标准接口有利于以后出现更好的驱动的时候做迁移。 + +##实例代码 +示例的数据库表结构如下所示,相应的建表SQL: + + CREATE TABLE `userinfo` ( + `uid` INTEGER PRIMARY KEY AUTOINCREMENT, + `username` VARCHAR(64) NULL, + `departname` VARCHAR(64) NULL, + `created` DATE NULL + ); + + CREATE TABLE `userdeatail` ( + `uid` INT(10) NULL, + `intro` TEXT NULL, + `profile` TEXT NULL, + PRIMARY KEY (`uid`) + ); + +看下面Go程序是如何操作数据库表数据:增删改查 + + package main + + import ( + "database/sql" + "fmt" + _ "github.com/mattn/go-sqlite3" + ) + + func main() { + db, err := sql.Open("sqlite3", "./foo.db") + checkErr(err) + + //插入数据 + stmt, errs := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?") + checkErr(errs) + + res, errres := stmt.Exec("astaxie", "研发部门", "2012-12-09") + checkErr(errres) + + id, errid := res.LastInsertId() + checkErr(errid) + + fmt.Println(id) + //更新数据 + stmt, errs = db.Prepare("update userinfo set username=? where uid=?") + checkErr(errs) + + res, errres = stmt.Exec("astaxieupdate", id) + checkErr(errres) + + affect, erraff := res.RowsAffected() + checkErr(erraff) + + fmt.Println(affect) + + //查询数据 + rows, errrow := db.Query("SELECT * FROM userinfo") + checkErr(errrow) + + 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, errrow = db.Prepare("delete from userinfo where uid=?") + checkErr(errrow) + + res, errres = stmt.Exec(id) + checkErr(errres) + + affect, erraff = res.RowsAffected() + checkErr(erraff) + + fmt.Println(affect) + + } + + func checkErr(err error) { + if err != nil { + panic(err) + } + } + + +我们可以看到上面的代码和MySQL例子里面的代码几乎是一模一样的,唯一改变的就是导入的驱动改变了,然后调用`sql.Open`是采用了SQLite的方式打开。 + + +>sqlite管理工具:http://sqliteadmin.orbmu2k.de/ + +>可以方便的新建数据库管理。 ## links * [目录]() diff --git a/5.4.md b/5.4.md index c565b8c..17ed59f 100644 --- a/5.4.md +++ b/5.4.md @@ -1,5 +1,118 @@ #5.4使用PostgreSQL数据库 +PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD-风格许可证下发行。它提供了相对其他开放源代码数据库系统(比如 MySQL 和 Firebird),和对专有系统比如 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server的一种选择。 + +PostgreSQL和MySQL比较,它更加庞大一点,因为它是用来替代Oracle而设计的。所以在企业应用中采用PostgreSQL是一个明智的选择。 + +现在MySQL被Oracle收购之后,有传闻Oracle正在逐步的封闭MySQL,也许将来我们会选择PostgreSQL作为我们后端数据库。 + +##驱动 +Go实现的支持PostgreSQL的驱动还是挺多的,发现国外很多人使用这个数据库。 + +- https://github.com/bmizerany/pq 支持database/sql驱动,纯Go写的 +- https://github.com/jbarham/gopgsqldriver 支持database/sql驱动,纯Go写的 +- https://github.com/lxn/go-pgsql 支持database/sql驱动,纯Go写的 + +这里演示我采用了第一个驱动,这个库目前在Go里面使用的人多,在github上也比较活跃。 +##实例代码 +数据库建表语句: + + CREATE TABLE userinfo + ( + uid serial NOT NULL, + username character varying(100) NOT NULL, + departname character varying(500) NOT NULL, + Created date, + CONSTRAINT userinfo_pkey PRIMARY KEY (uid) + ) + WITH (OIDS=FALSE); + + CREATE TABLE userdeatail + ( + uid integer, + intro character varying(100), + profile character varying(100) + ) + WITH(OIDS=FALSE); + +看下面这个Go如何操作数据库表数据:增删改查 + +package main + + import ( + "database/sql" + "fmt" + _ "github.com/bmizerany/pq" + ) + + func main() { + db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable") + checkErr(err) + + //插入数据 + stmt, errs := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) RETURNING uid") + checkErr(errs) + + res, errres := stmt.Exec("astaxie", "研发部门", "2012-12-09") + checkErr(errres) + + //pg不支持这个函数,因为他没有类似MySQL的自增ID + id, errid := res.LastInsertId() + checkErr(errid) + + fmt.Println(id) + + //更新数据 + stmt, errs = db.Prepare("update userinfo set username=$1 where uid=$2") + checkErr(errs) + + res, errres = stmt.Exec("astaxieupdate", 1) + checkErr(errres) + + affect, erraff := res.RowsAffected() + checkErr(erraff) + + fmt.Println(affect) + + //查询数据 + rows, errrow := db.Query("SELECT * FROM userinfo") + checkErr(errrow) + + 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, errrow = db.Prepare("delete from userinfo where uid=$1") + checkErr(errrow) + + res, errres = stmt.Exec(1) + checkErr(errres) + + affect, erraff = res.RowsAffected() + checkErr(erraff) + + fmt.Println(affect) + + } + + func checkErr(err error) { + if err != nil { + panic(err) + } + } + + +上面的代码我们可以看到,PostgreSQL传递参数是通过`$1`,`$2`这种方式来指定要传递的参数,而不是MySQL中的`?`,所以在处理的时候稍微有点不一样。还有pg不支持LastInsertId函数,因为PostgreSQL内部没有实现类似MySQL的自增ID返回,其他的代码几乎是一模一样。 ## links * [目录]() -- GitLab