go 数据库操作

    一、  nosql 数据库操作

 

      1、redis

   版本1:

     github地址: 

     https://github.com/garyburd/redigo

 

    文档地址: 

   http://godoc.org/github.com/garyburd/redigo/redis

连接redis

package main
import (
    "fmt"
    "github.com/garyburd/redigo/redis"
)

func main() {
    c, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c.Close()
}

 读写 默认(值永远不会过期)

 

_, err = c.Do("SET", "mykey", "superWang")
    if err != nil {
        fmt.Println("redis set failed:", err)
    }

    username, err := redis.String(c.Do("GET", "mykey"))
    if err != nil {
        fmt.Println("redis get failed:", err)
    } else {
        fmt.Printf("Get mykey: %v \n", username)
    }

 SET的附加参数设置过期:

 _, err = c.Do("SET", "mykey", "superWang", "EX", "5")

 批量写入读取

   MGET key [key …] 
  MSET key value [key value …]

批量写入读取对象(Hashtable) 
  HMSET key field value [field value …] 
  HMGET key field [field …]

检测值是否存在 
  EXISTS key

is_key_exit, err := redis.Bool(c.Do("EXISTS", "mykey1"))
    if err != nil {
        fmt.Println("error:", err)
    } else {
        fmt.Printf("exists or not: %v \n", is_key_exit)
    }

 删除  DEL key [key …]

 _, err = c.Do("DEL", "mykey")
    if err != nil {
        fmt.Println("redis delelte failed:", err)
    }

 读写json到redis

package main

import (
    "encoding/json"
    "fmt"

    "github.com/garyburd/redigo/redis"
)

func main() {
    c, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c.Close()

    key := "profile"
    imap := map[string]string{"username": "666", "phonenumber": "888"}
    value, _ := json.Marshal(imap)

    n, err := c.Do("SETNX", key, value)
    if err != nil {
        fmt.Println(err)
    }
    if n == int64(1) {
        fmt.Println("success")
    }

    var imapGet map[string]string

    valueGet, err := redis.Bytes(c.Do("GET", key))
    if err != nil {
        fmt.Println(err)
    }

    errShal := json.Unmarshal(valueGet, &imapGet)
    if errShal != nil {
        fmt.Println(err)
    }
    fmt.Println(imapGet["username"])
    fmt.Println(imapGet["phonenumber"])
}

 设置过期时间 

   EXPIRE key seconds

// 设置过期时间为24小时  
n, _ := rs.Do("EXPIRE", key, 24*3600)  
if n == int64(1) {  
    fmt.Println("success")  
}  

 列表操作 

命令:

redis 127.0.0.1:6379> LPUSH runoobkey redis
(integer) 1
redis 127.0.0.1:6379> LPUSH runoobkey mongodb
(integer) 2
redis 127.0.0.1:6379> LPUSH runoobkey mysql
(integer) 3
redis 127.0.0.1:6379> LRANGE runoobkey 0 10

1) "mysql"
2) "mongodb"
3) "redis"

 

package main

import (
    "fmt"

    "github.com/garyburd/redigo/redis"
)

func main() {
    c, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c.Close()

    _, err = c.Do("lpush", "runoobkey", "redis")
    if err != nil {
        fmt.Println("redis set failed:", err)
    }

    _, err = c.Do("lpush", "runoobkey", "mongodb")
    if err != nil {
        fmt.Println("redis set failed:", err)
    }
    _, err = c.Do("lpush", "runoobkey", "mysql")
    if err != nil {
        fmt.Println("redis set failed:", err)
    }

    values, _ := redis.Values(c.Do("lrange", "runoobkey", "0", "100"))

    for _, v := range values {
        fmt.Println(string(v.([]byte)))
    }
}

 管道

请求/响应服务可以实现持续处理新请求,即使客户端没有准备好读取旧响应。这样客户端可以发送多个命令到服务器而无需等待响应,最后在一次读取多个响应。这就是管道化(pipelining),这个技术在多年就被广泛使用了。距离,很多POP3协议实现已经支持此特性,显著加速了从服务器下载新邮件的过程。 
Redis很早就支持管道化,所以无论你使用任何版本,你都可以使用管道化技术

 

连接支持使用Send(),Flush(),Receive()方法支持管道化操作

Send(commandName string, args ...interface{}) error
Flush() error
Receive() (reply interface{}, err error)

 Send向连接的输出缓冲中写入命令。Flush将连接的输出缓冲清空并写入服务器端。Recevie按照FIFO顺序依次读取服务器的响应。下例展示了一个简单的管道:

c.Send("SET", "foo", "bar")
c.Send("GET", "foo")
c.Flush()
c.Receive() // reply from SET
v, err = c.Receive() // reply from GET

 Do方法组合了Send,Flush和 Receive方法。Do方法先写入命令,然后清空输出buffer,最后接收全部挂起响应包括Do方发出的命令的结果。如果任何响应中包含一个错误,Do返回错误。如果没有错误,Do方法返回最后一个响应。

  版本2:

开源库go-redis/redis的使用

 

github地址: 

https://github.com/go-redis/redis

 

文档地址: 

 

https://godoc.org/github.com/go-redis/redis

 

package main

import (
    "fmt"

    "github.com/go-redis/redis"
)

func main() {
    client := redis.NewClient(&redis.Options{
        Addr:     "127.0.0.1:6379",
        Password: "", // no password set
        DB:       0,  // use default DB
    })

    pong, err := client.Ping().Result()
    fmt.Println(pong, err)

    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 exists")
    } else if err != nil {
        panic(err)
    } else {
        fmt.Println("key2", val2)
    }
}

   版本3:

github地址: 

https://github.com/astaxie/goredis

package main
import (
    "github.com/astaxie/goredis"
    "fmt"
)
func main() {
    var client goredis.Client
    // 
设置端口为
redis
默认端口
    client.Addr = "127.0.0.1:6379"
    //
字符串操作
    client.Set("a", []byte("hello"))
    val, _ := client.Get("a")
    fmt.Println(string(val))
    client.Del("a")
    //list
操作
    vals := []string{"a", "b", "c", "d", "e"}
    for _, v := range vals {
        client.Rpush("l", []byte(v))
    }
    dbvals,_ := client.Lrange("l", 0, 4)
    for i, v := range dbvals {
        println(i,":",string(v))
    }
    client.Del("l")
}

  二、  mongodb 数据库操作

  先安装Golang和MongoDB

  安装bzr版本工具(mgo使用Bazaar作为版本控制系统,因安装的时候需要去Bazaar拉取代码)

   执行:

  go get labix.org/v2/mgo

如果是本机,并且MongoDB是默认端口27017启动的话,下面几种方式都可以。

session, err := mgo.Dial("")
session, err := mgo.Dial("localhost")
session, err := mgo.Dial("127.0.0.1")
session, err := mgo.Dial("localhost:27017")
session, err := mgo.Dial("127.0.0.1:27017")

 如果不在本机或端口不同,传入相应的地址即可。如:

      mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb

通过Session.DB()来切换相应的数据库。

  实现:

import (
    "fmt"
    "labix.org/v2/mgo"
    "labix.org/v2/mgo/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()
    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 {
        panic(err)
    }
    result := Person{}
    err = c.Find(bson.M{"name": "Ale"}).One(&result)
    if err != nil {
        panic(err)
    }
    fmt.Println("Phone:", result.Phone)
}

 切换数据库

猜你喜欢

转载自ogc.iteye.com/blog/2392215