加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang数据库、缓存

发布时间:2020-12-16 09:22:52 所属栏目:大数据 来源:网络整理
导读:database/sql 接口 Go官方没有提供数据库驱动,而是为开发数据库驱动定义了一些标准接口 database/sql ,开发者可以根据定义的接口来开发相应的数据库驱动,这样做有一个好处,只要是按照标准接口开发的代码, 以后需要迁移数据库时,不需要任何修改。 MySQL

database/sql 接口

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

MySQL

常用的有如下几种:

  • 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写。

这里使用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:%dn",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:%[email?protected](%s)/%s?charset=utf8mb4",user,password,address,database)
    db,dsn)
    return db,errors.Wrap(err,"can not connect db.")
}

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写的

这里使用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:%[email?protected]%s/%s?sslmode=verify-full",err := sql.Open("postgres","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,dbname)
    return db,"can not connect db.")
}

redis

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

  • https://github.com/go-redis/redis (推荐)
  • https://github.com/gomodule/redigo (推荐)
  • https://github.com/hoisie/redis
  • https://github.com/alphazero/Go-Redis
  • https://github.com/simonz05/godis

前面两个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 。

安装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

常用驱动:

  • https://github.com/olivere/elastic
    Go 语言的 Elasticsearch 客户端。(推荐)

  • https://github.com/mattbaird/elastigo mattbaird/elastigo: A Go (golang) based Elasticsearch client library.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读