database/sql 接口

Go官方没有提供数据库驱动,而是为开发数据库驱动定义了一些标准接口database/sql,开发者可以根据定义的接口来开发相应的数据库驱动,这样做有一个好处,只要是按照标准接口开发的代码, 以后需要迁移数据库时,不需要任何修改。

MySQL

常用的有如下几种:

这里使用go-sql-driver/mysql驱动进行演示,原因是该库使用人数最多,且支持database/sql接口。

示例:

package main

import (
_ "github.com/go-sql-driver/mysql"
"database/sql"
"fmt"
) type User struct {
Id int
Name string
Gender int
Age int
} func checkErr(err error) {
if err != nil {
panic(err)
}
} func main() {
db, err := sql.Open("mysql", "root:@(127.0.0.1:3306)/test?charset=utf8")
checkErr(err) //查询
rows, err := db.Query("SELECT id,name,gender,age from user limit 2")
checkErr(err) var users []User
for rows.Next() {
var u User
rows.Scan(&u.Id, &u.Name, &u.Gender, &u.Age)
users = append(users, u)
} //fmt.Print(users)
for _,u := range users{
fmt.Printf("id:%d, name:%s, gender:%d, age:%d\n", u.Id, u.Name, u.Gender, u.Age)
}
}

输出:

id:1, name:allen, gender:1, age:20
id:2, name:alice, gender:2, age:18

新增:

stmt, err := db.Prepare("INSERT INTO user (name,age) VALUES (?, ?)")
checkErr(err)
res, err := stmt.Exec("golang", 10)
checkErr(err)
fmt.Println(res.LastInsertId())

输出:

26 <nil>

注:res.LastInsertId()返回的新增id和error。

更新:

stmt, err := db.Prepare("update user set age = ? where id = ?")
checkErr(err)
res, err := stmt.Exec(8, 26)
checkErr(err)
fmt.Println(res.RowsAffected())

输出:

1 <nil>

注:res.RowsAffected()返回的影响函数和error。

删除:

stmt, err := db.Prepare("DELETE FROM user where id = ?")
checkErr(err)
res, err := stmt.Exec( 26)
checkErr(err)
fmt.Println(res.RowsAffected()) //或者
//res, err := db.Exec("DELETE FROM user where id = 26")
//checkErr(err)
//fmt.Println(res.RowsAffected())

可以简单封装一下:

func NewMysqlClient() (*sql.DB, error) {
address := "127.0.0.1:3306"
user := "root"
password := ""
database := "test"
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4", user, password, address, database)
db, err := sql.Open("mysql", dsn)
return db, errors.Wrap(err, "can not connect db.")
}

PostgreSQL

常见驱动库:

这里使用lib/pq进行演示,因为该库使用的人数最多。

import (
"database/sql" _ "github.com/lib/pq"
) //获取客户端
func NewPostgreSQLClient() (*sql.DB, error) {
address := "127.0.0.1"
user := "pqgotest"
password := ""
database := "pqgotest"
dsn := fmt.Sprintf("%s://%s:%s@%s/%s?sslmode=verify-full", user, password, address, database)
db, err := sql.Open("postgres", dsn)
return db, errors.Wrap(err, "can not connect db.")
} func main() {
db, err := NewPostgreSQLClient()
if err != nil {
log.Fatal(err)
} age := 21
rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
//…
}

SQLite

驱动库:https://github.com/mattn/go-sqlite3

该驱动采用database/sql接口,所以使用起来和操作MySQL是一样的。

增删改查示例:

package main

import (
"database/sql"
"fmt" _ "github.com/mattn/go-sqlite3"
) //CREATE TABLE `userinfo` (
// `uid` INTEGER PRIMARY KEY AUTOINCREMENT,
// `username` VARCHAR(64) NULL,
// `departname` VARCHAR(64) NULL,
// `created` DATE NULL
//); func checkErr(err error) {
if err != nil {
panic(err)
}
} type UserInfo struct {
uid int
username string
departname string
created string
} func main() {
db, err := sql.Open("sqlite3", "./test_sqlite.db")
checkErr(err) //增加
stmt, err := db.Prepare("insert into userinfo(username,departname,created) values(?, ?, ?)")
checkErr(err) res, err := stmt.Exec("yjc", "test", "2018-08-12")
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("golang", 1)
checkErr(err) affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect) //查询
rows, err := db.Query("select * from userinfo")
checkErr(err) var user UserInfo
var users []UserInfo
for rows.Next() {
rows.Scan(&user.uid, &user.username, &user.departname, &user.created)
users = append(users, user)
} fmt.Println(users) //删除
stmt, err = db.Prepare("delete from userinfo where uid = ?")
checkErr(err) res, err = stmt.Exec(2)
checkErr(err) affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect) }

可以简单封装一下:

func NewSqliteClient() (*sql.DB, error) {
dbname := "./test_sqlite.db"
db, err := sql.Open("sqlite3", dbname)
return db, errors.Wrap(err, "can not connect db.")
}

redis

Go目前支持redis的驱动有如下

前面两个Star数是最多的,生产环境推荐从前面两个选择。使用上go-redis/redis简单些。

go-redis/redis示例

//获取客户端
func NewRedisClient() *redis.Client {
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
}) //pong, err := client.Ping().Result()
//fmt.Println(pong, err)
// Output: PONG <nil>
return client
} //test
func ExampleClient() {
client := NewRedisClient()
defer client.Close() err := client.Set("key", "value", 0).Err()
if err != nil {
panic(err)
} val, err := client.Get("key").Result()
if err != nil {
panic(err)
}
fmt.Println("key", val) val2, err := client.Get("key2").Result()
if err == redis.Nil {
fmt.Println("key2 does not exist")
} else if err != nil {
panic(err)
} else {
fmt.Println("key2", val2)
}
// Output: key value
// key2 does not exist
}

mongoDB

目前Go支持mongoDB最好的驱动就是mgo,地址:http://labix.org/mgo

2019-08-18 更新:很长一段时间,MongoDB 的 Go 语言驱动一直使用的 mgo 这个,但由于作者工作中不再使用 MongoDB,出于精力等方面的考虑,该项目不再维护。而且我们有了官方出品的驱动,自然应该使用它了。地址:https://github.com/mongodb/mongo-go-driver。

安装mgo:

go get gopkg.in/mgo.v2

示例:

package main

import (
"fmt"
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
) type Person struct {
Name string
Phone string
} func main() {
session, err := mgo.Dial("server1.example.com,server2.example.com")
if err != nil {
panic(err)
}
defer session.Close() // Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true) c := session.DB("test").C("people")
err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
} result := Person{}
err = c.Find(bson.M{"name": "Ale"}).One(&result)
if err != nil {
log.Fatal(err)
} fmt.Println("Phone:", result.Phone)
}

Elasticsearch

常用驱动:

Go如何使用数据库、缓存的更多相关文章

  1. ASP.NET缓存全解析6:数据库缓存依赖 转自网络原文作者李天平

    更多的时候,我们的服务器性能损耗还是在查询数据库的时候,所以对数据库的缓存还是显得特别重要,上面几种方式都可以实现部分数据缓存功能.但问题是我们的数据有时候是在变化的,这样用户可能在缓存期间查询的数据 ...

  2. Apache Ignite——新一代数据库缓存系统

    [编者按]飞速增长的数据需要大量存储,对这些数据的管理也不是一件容易的事.但相比于存储和管理,如何处理数据才是开发人员真正的挑战.对于TB级别数据的存储和处理通常会让开发人员陷入速度.可扩展性和开销的 ...

  3. (转)ASP.NET缓存全解析6:数据库缓存依赖

    ASP.NET缓存全解析文章索引 ASP.NET缓存全解析1:缓存的概述 ASP.NET缓存全解析2:页面输出缓存 ASP.NET缓存全解析3:页面局部缓存 ASP.NET缓存全解析4:应用程序数据缓 ...

  4. 网站优化指南之数据库缓存、CDN与云存储

    1 数据库缓存. 常见的做法是用内存做cache,把数据库里的内容提前取出读到内存里,用户再请求时,就不直接读数据库,而是读内存里的数据,从而缓解了数据库的压力. 过去比较常用的缓存软件是memcac ...

  5. Java数据库缓存思路

    为什么要用缓存?如果问这个问题说明你还是新手,数据库吞吐量毕竟有限,每秒读写5000次了不起了,如果不用缓存,假设一个页面有100个数据库操作,50个用户并发数据库就歇菜,这样最多能支撑的pv也就50 ...

  6. Asp.net数据库缓存依赖

    Asp.net数据库缓存依赖 更多的时候,我们的服务器性能损耗还是在查询数据库的时候,所以对数据库的缓存还是显得特别重要,上面几种方式都可以实现部分数据缓存功能.但问题是我们的数据有时候是在变化的,这 ...

  7. Sql缓存依赖--数据库缓存

    •依赖于文件内容CacheDependency cDep = new CacheDependency(filePath); •依赖于数据库内容(轮询机制/通知机制)一:轮询机制 1.在数据库新建版本表 ...

  8. Django Cache缓存系统学习--数据库缓存

    Django是动态网站,用户每一次请求页面,服务器都会执行以下操作:数据库查询.渲染模版.执行业务逻辑,最后生成用户可查看的页面.当访问量比较大的时候,会消耗掉大量的资源,这时候就会考虑到缓存问题. ...

  9. 用Redis作Mysql数据库缓存

    使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按 ...

  10. redis(二)--用Redis作MySQL数据库缓存

    用Redis作MySQL数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...

随机推荐

  1. c# 多线程多个参数

    for (int i = 0; i <count; i++) //根据选择的串口号数量创建对应数量的线程 { thread = new Thread(new ParameterizedThrea ...

  2. CSS换行知识

    换行规则 CSS可以指定文字多行时换行的规则,说白了就是指定哪些地方可以换行 相关属性 word-break The word-break CSS property sets whether line ...

  3. 分布式共识算法 (三) Raft算法

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.引子 1.1 介绍 Raft 是一种为了管 ...

  4. oracle 错误 ORA-00020问题解析

    问题描述 [oracle@xiaowu ~]$ sqlplus / as sysdba SQL*Plus: Release Production on Wed Oct :: Copyright (c) ...

  5. 团队作业第五次—项目冲刺-Day6

    Day6 part1-SCRUM: 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 hunter--冲刺集合 团队名称 hunte ...

  6. Visual Studio 2019(VS2019)正式版注册码秘钥

    Visual Studio 2019 EnterpriseBF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 ProfessionalNYWVH-HT4X ...

  7. win10配置jdk1.8环境变量

    1,安装好jdk之后,目录如下 2,右键计算机 - 属性 - 高级系统设置 3,环境变量 4,新增系统变量JAVA_HOME,输入内容D:\work\Program Files\Java\jdk1.8 ...

  8. python面试题第一份

    阅读目录 1 Python的函数参数传递 2 Python中的元类(metaclass) 3 @staticmethod和@classmethod 4 类变量和实例变量 5 Python自省 6 字典 ...

  9. java json解析(转)

    转自:https://www.cnblogs.com/sunnywindycloudy/p/8343013.html 给服务端发送请求后,服务端会返回一连串的数据,这些数据在大部分情况下都是XML格式 ...

  10. Linux启动/停止/重启gitlab

    # Start all GitLab components sudo gitlab-ctl start # Stop all GitLab components sudo gitlab-ctl sto ...