database/sql 接口

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

MySQL

常用的有如下几种:

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

示例:

  1. package main
  2. import (
  3. _ "github.com/go-sql-driver/mysql"
  4. "database/sql"
  5. "fmt"
  6. )
  7. type User struct {
  8. Id int
  9. Name string
  10. Gender int
  11. Age int
  12. }
  13. func checkErr(err error) {
  14. if err != nil {
  15. panic(err)
  16. }
  17. }
  18. func main() {
  19. db, err := sql.Open("mysql", "root:@(127.0.0.1:3306)/test?charset=utf8")
  20. checkErr(err)
  21. //查询
  22. rows, err := db.Query("SELECT id,name,gender,age from user limit 2")
  23. checkErr(err)
  24. var users []User
  25. for rows.Next() {
  26. var u User
  27. rows.Scan(&u.Id, &u.Name, &u.Gender, &u.Age)
  28. users = append(users, u)
  29. }
  30. //fmt.Print(users)
  31. for _,u := range users{
  32. fmt.Printf("id:%d, name:%s, gender:%d, age:%d\n", u.Id, u.Name, u.Gender, u.Age)
  33. }
  34. }

输出:

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

新增:

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

输出:

  1. 26 <nil>

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

更新:

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

输出:

  1. 1 <nil>

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

删除:

  1. stmt, err := db.Prepare("DELETE FROM user where id = ?")
  2. checkErr(err)
  3. res, err := stmt.Exec( 26)
  4. checkErr(err)
  5. fmt.Println(res.RowsAffected())
  6. //或者
  7. //res, err := db.Exec("DELETE FROM user where id = 26")
  8. //checkErr(err)
  9. //fmt.Println(res.RowsAffected())

可以简单封装一下:

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

PostgreSQL

常见驱动库:

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

  1. import (
  2. "database/sql"
  3. _ "github.com/lib/pq"
  4. )
  5. //获取客户端
  6. func NewPostgreSQLClient() (*sql.DB, error) {
  7. address := "127.0.0.1"
  8. user := "pqgotest"
  9. password := ""
  10. database := "pqgotest"
  11. dsn := fmt.Sprintf("%s://%s:%s@%s/%s?sslmode=verify-full", user, password, address, database)
  12. db, err := sql.Open("postgres", dsn)
  13. return db, errors.Wrap(err, "can not connect db.")
  14. }
  15. func main() {
  16. db, err := NewPostgreSQLClient()
  17. if err != nil {
  18. log.Fatal(err)
  19. }
  20. age := 21
  21. rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
  22. //…
  23. }

SQLite

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

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

增删改查示例:

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. _ "github.com/mattn/go-sqlite3"
  6. )
  7. //CREATE TABLE `userinfo` (
  8. // `uid` INTEGER PRIMARY KEY AUTOINCREMENT,
  9. // `username` VARCHAR(64) NULL,
  10. // `departname` VARCHAR(64) NULL,
  11. // `created` DATE NULL
  12. //);
  13. func checkErr(err error) {
  14. if err != nil {
  15. panic(err)
  16. }
  17. }
  18. type UserInfo struct {
  19. uid int
  20. username string
  21. departname string
  22. created string
  23. }
  24. func main() {
  25. db, err := sql.Open("sqlite3", "./test_sqlite.db")
  26. checkErr(err)
  27. //增加
  28. stmt, err := db.Prepare("insert into userinfo(username,departname,created) values(?, ?, ?)")
  29. checkErr(err)
  30. res, err := stmt.Exec("yjc", "test", "2018-08-12")
  31. checkErr(err)
  32. id, err := res.LastInsertId()
  33. checkErr(err)
  34. fmt.Println(id)
  35. //更新
  36. stmt, err = db.Prepare("update userinfo set username = ? where uid = ?")
  37. checkErr(err)
  38. res, err = stmt.Exec("golang", 1)
  39. checkErr(err)
  40. affect, err := res.RowsAffected()
  41. checkErr(err)
  42. fmt.Println(affect)
  43. //查询
  44. rows, err := db.Query("select * from userinfo")
  45. checkErr(err)
  46. var user UserInfo
  47. var users []UserInfo
  48. for rows.Next() {
  49. rows.Scan(&user.uid, &user.username, &user.departname, &user.created)
  50. users = append(users, user)
  51. }
  52. fmt.Println(users)
  53. //删除
  54. stmt, err = db.Prepare("delete from userinfo where uid = ?")
  55. checkErr(err)
  56. res, err = stmt.Exec(2)
  57. checkErr(err)
  58. affect, err = res.RowsAffected()
  59. checkErr(err)
  60. fmt.Println(affect)
  61. }

可以简单封装一下:

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

redis

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

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

go-redis/redis示例

  1. //获取客户端
  2. func NewRedisClient() *redis.Client {
  3. client := redis.NewClient(&redis.Options{
  4. Addr: "localhost:6379",
  5. Password: "", // no password set
  6. DB: 0, // use default DB
  7. })
  8. //pong, err := client.Ping().Result()
  9. //fmt.Println(pong, err)
  10. // Output: PONG <nil>
  11. return client
  12. }
  13. //test
  14. func ExampleClient() {
  15. client := NewRedisClient()
  16. defer client.Close()
  17. err := client.Set("key", "value", 0).Err()
  18. if err != nil {
  19. panic(err)
  20. }
  21. val, err := client.Get("key").Result()
  22. if err != nil {
  23. panic(err)
  24. }
  25. fmt.Println("key", val)
  26. val2, err := client.Get("key2").Result()
  27. if err == redis.Nil {
  28. fmt.Println("key2 does not exist")
  29. } else if err != nil {
  30. panic(err)
  31. } else {
  32. fmt.Println("key2", val2)
  33. }
  34. // Output: key value
  35. // key2 does not exist
  36. }

mongoDB

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

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

安装mgo:

  1. go get gopkg.in/mgo.v2

示例:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "gopkg.in/mgo.v2"
  6. "gopkg.in/mgo.v2/bson"
  7. )
  8. type Person struct {
  9. Name string
  10. Phone string
  11. }
  12. func main() {
  13. session, err := mgo.Dial("server1.example.com,server2.example.com")
  14. if err != nil {
  15. panic(err)
  16. }
  17. defer session.Close()
  18. // Optional. Switch the session to a monotonic behavior.
  19. session.SetMode(mgo.Monotonic, true)
  20. c := session.DB("test").C("people")
  21. err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
  22. &Person{"Cla", "+55 53 8402 8510"})
  23. if err != nil {
  24. log.Fatal(err)
  25. }
  26. result := Person{}
  27. err = c.Find(bson.M{"name": "Ale"}).One(&result)
  28. if err != nil {
  29. log.Fatal(err)
  30. }
  31. fmt.Println("Phone:", result.Phone)
  32. }

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. Graphviz学习

    (入门教程)[https://www.luogu.com.cn/blog/umr/graphviz]

  2. python总结十

    1.代码int('20',8)的返回结果是:16 2.日志的统计和记录对于程序开发来说非常重要,python提供了非常好用的日志模块logging 3.元祖修改 4.python内置映射类型称为字典 ...

  3. win7升级win10

    win7的系统看起来不是特别爽,还是win10用得顺手. win7升级win10: https://jingyan.baidu.com/article/066074d60391e2c3c31cb04e ...

  4. 修咻咻对追光的人、云打印团队的Beta产品测试报告

    修咻咻对追光的人.云打印团队的Beta产品测试报告 作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Beta冲刺(团队) 团队目标 切实可行的计算机协会维修预约平 ...

  5. hdu6546 Function

    Function \(\text{Alice}\) 有 \(n\) 个二次函数 \(F_i(x)=a_ix^2+b_ix+c_i(i \in [1,n])\). 现在他想在 \(\sum_{i=1}^ ...

  6. 企业微信同步LDAP

    1.需求 定期同步企业微信的用户信息到 LDAP 中,当有新用户时,会自动发送LDAP的账号密码给该用户邮箱. 2.环境 python 3.x 需要安装两个模块 pip install ldap3 r ...

  7. html。PROGRESS进度条使用测试

    效果图 : 代码: ----------------------------------- //本文来自:https://www.cnblogs.com/java2sap/p/11199126.htm ...

  8. python 属性描述符

    import numbers class IntField: # 一个类只要实现了这个魔法函数,那么它就是属性描述符 #数据描述符 def __get__(self, instance, owner) ...

  9. Python转义序列

    正则表达式参考:https://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html

  10. Java 中要将 String 类型转化为 int 类型

    在 Java 中要将 String 类型转化为 int 类型时,需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换. 例1: 1 2 3 4 5 6 S ...