zoukankan      html  css  js  c++  java
  • Golang:MySQL&Redis

    Beego: 原生方式使用MySQL

    package controllers
    
    import (
        "database/sql"
        "fmt"
        "github.com/astaxie/beego"
        _ "github.com/go-sql-driver/mysql"
    )
    
    type MysqlController struct {
        beego.Controller
    }
    
    func (c *MysqlController) Get() {
        // 连接数据库
        db, err := sql.Open("mysql", "root:Pd940810@tcp(127.0.0.1:3306)/test?charset=utf8")
        if err != nil {
            beego.Info("连接数据库出错", err)
            return
        }
        // 关闭数据库连接
        defer db.Close()
    
        // 创建表
        _, err = db.Exec("create table userInfo(id int not null auto_increment primary key, name varchar(11) unique)")
        if err != nil {
            fmt.Printf("创建表出错:%v", err)
            return
        }
    
        // 插入数据
        _, err = db.Exec("insert into userInfo (name) values (?)", "乔治")
        if err != nil {
            fmt.Printf("创建表出错:%v", err)
            return
        }
    
        // 查询数据
        rows, err := db.Query("select * from userInfo")
        type UserInfo struct {
            Id int
            Name string
        }
        var u UserInfo
        for rows.Next() {
            err = rows.Scan(&u.Id, &u.Name)
            fmt.Println(u)
        }
    
        // 更新数据
        _, err = db.Exec("update userInfo set name='pd' where id=1")
    
        c.Ctx.WriteString("testing...")
    }
    
    controllers/mysql.go
    

    Redis

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。

    安装

    • Window 下安装
      Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择
    1. 启动服务器端
      打开一个cmd窗口 使用cd命令切换目录到redis根目录(例如 C: edis) 运行
        //默认启动
        redis-server.exe
    
        //根据修改的配置文件启动
        redis-server.exe redis.conf
    
    1. 运行客户端
      切换到 redis 目录下运行:
        redis-cli.exe -h 127.0.0.1 -p 6379  //127.0.0.1 是本机 IP ,6379 是 redis 服务端口。
    
        //测试
        redis> set myKey abc
        OK
        redis> get myKey
        abc
    
        $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz
        $ tar xzf redis-5.0.5.tar.gz
        $ cd redis-5.0.5
        $ make
    

    make完后 redis-5.0.5目录下会出现编译后的redis服务程序redis-server,还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下:

    1. 启动redis服务.
        //默认启动
        $ ./redis-server    //注意这种方式启动redis 使用的是默认配置。也可以通过启动参数告诉redis使用指定配置文件使用下面命令启动。
    
        //根据修改的配置文件启动
        $ cd src
        $ ./redis-server ../redis.conf      //redis.conf 是一个默认的配置文件。我们可以根据需要使用自己的配置文件。
    
    1. 运行客户端测试
        $ cd src
        $ ./redis-cli
        //测试
        redis> set foo bar
        OK
        redis> get foo
        "bar"
    

    配置

    Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf)。

    • 查看配置
      你可以通过 CONFIG 命令查看或设置配置项。
        CONFIG GET 命令基本语法:
        redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME
        ......
        //使用 * 号获取所有配置项:
        redis 127.0.0.1:6379> CONFIG GET *
    
    • 编辑配置
      可以通过修改 redis.conf 文件或使用 CONFIG set 命令来修改配置。
        CONFIG SET 命令基本语法:
        redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
        OK
    
    • 参数说明

    Redis配置参数说明

    数据类型

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

    Redis数据类型

    Redis 命令参考

    Redis 命令参考

    Golang 操作 Redis

    • 安装第三方开源 Redis 库
    1. 使用第三方开源的 redis 库: github.com/garyburd/redigo/redis
        其他golang可用的第三方开源库:
        1. https://github.com/go-redis/redis
        2. https://github.com/gomodule/redigo
    
    1. 在使用 Redis 前,先安装第三方 Redis 库,在 GOPATH 路径下执行安装指令:
        $GOPATH >go get github.com/garyburd/redigo/redis
    
        //特别说明: 在安装 Redis 库前,确保已经安装并配置了 Git, 因为 是从 github 下载安装 Redis 库的,需要使用到 Git。 如果没有安装配置过 Git,请参考: 如何安装配置 Git
    
    1. 引入包 "github.com/garyburd/redigo/redis"
        import "github.com/garyburd/redigo/redis" //引入redis包 
    
    • Golang对Redis基本操作
    1. 链接到 redis
        conn, err := redis.Dial("tcp", "127.0.0.1:6379")
    
    1. 通过go 向redis写入数据
    2. 通过go 向redis读取数据 (因为返回 r是 interface{},我们需要转换成相应的值类型)
        //写入字符串类型
    	_, err = conn.Do("Set", "name", "tom")
        //读取String类型
        r, err := redis.String(conn.Do("Get", "name"))
    
        //列表类型
        _, err = conn.Do("LPUSH", "list1", "ele1","ele2","ele3")
    
        res, err := redis.String(conn.Do("LPOP", "list1"))
    
        //hash类型
        _, err = conn.Do("HSet", "user", "name", "john")
        r1, err := redis.String(conn.Do("HGet","user", "name"))
    
        _, err = conn.Do("HSet", "user", "age", 18)
        r2, err := redis.Int(conn.Do("HGet","user", "age"))
    
        //多个值
        _, err = conn.Do("HMSet", "user", "name", "john", "age", 19)
        //多个值
        r, err := redis.Strings(conn.Do("HMGet","user02", "name", "age"))
        for i, v := range r {
    		fmt.Printf("r[%d]=%s
    ", i, v)
    	}
    
    1. 通过 Go给 key-value 设置有效时间
        //给 name 数据设置有效时间为 10s
        _, err = c.Do("expire", "name", 10)
    
    
    1. 关闭链接
        conn.Close()
    
    • Redis 链接池
      通过 Golang 对 Redis 操作, 还可以通过 Redis 链接池, 流程如下:
    1. 事先初始化一定数量的链接,放入到链接池
    2. 当 Go 需要操作 Redis 时,直接从 Redis 链接池取出链接即可。
    3. 这样可以节省临时获取 Redis 链接的时间,从而提高效率.
        //定义一个全局的pool
        var pool *redis.Pool
    
        //当启动程序时,就初始化连接池
        func init() {
            pool = &redis.Pool{
                MaxIdle: 8, //最大空闲链接数
                MaxActive: 0, // 表示和数据库的最大链接数, 0 表示没有限制
                IdleTimeout: 100, // 最大空闲时间
                Dial: func() (redis.Conn, error) { // 初始化链接的代码, 链接哪个ip的redis
                    return redis.Dial("tcp", "localhost:6379")
                },
            }	
        }
        func main() {
            //先从pool 取出一个链接
            conn := pool.Get()
            defer conn.Close()
            ...
            //我们要从pool 取出链接,一定保证链接池是没有关闭
            //如果pool.Close(),则无法获取链接
        }
    
    • Pipelining(管道)
      Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

    管道操作可以理解为并发操作,并通过Send(),Flush(),Receive()三个方法实现。

    客户端可以使用send()方法一次性向服务器发送一个或多个命令,命令发送完毕时,使用flush()方法将缓冲区的命令输入一次性发送到服务器,客户端再使用Receive()方法依次按照先进先出的顺序读取所有命令操作结果。

    管道技术最显著的优势是提高了 redis 服务的性能。

        Send(commandName string, args ...interface{}) error
        Flush() error
        Receive() (reply interface{}, err error)
    
    1. Send:发送命令至缓冲区
    2. Flush:清空缓冲区,将命令一次性发送至服务器
    3. Recevie:依次读取服务器响应结果,当读取的命令未响应时,该操作会阻塞。
        package main
    
        import (
        "github.com/garyburd/redigo/redis"
        "fmt"
        )
        func main()  {
            conn,err := redis.Dial("tcp","10.1.210.69:6379")
            if err != nil {
                fmt.Println("connect redis error :",err)
                return
            }
            defer conn.Close()
            conn.Send("HSET", "student","name", "wd","age","22")
            conn.Send("HSET", "student","Score","100")
            conn.Send("HGET", "student","age")
            conn.Flush()
    
            res1, err := conn.Receive()
            fmt.Printf("Receive res1:%v 
    ", res1)
            res2, err := conn.Receive()
            fmt.Printf("Receive res2:%v
    ",res2)
            res3, err := conn.Receive()
            fmt.Printf("Receive res3:%s
    ",res3)
        }
    
        控制台打印结果:
        Receive res1:0 
        Receive res2:0
        Receive res3:22
    
    • 发布/订阅
      redis本身具有发布订阅的功能,其发布订阅功能通过命令SUBSCRIBE(订阅)/PUBLISH(发布)实现,并且发布订阅模式可以是多对多模式还可支持正则表达式,发布者可以向一个或多个频道发送消息,订阅者可订阅一个或者多个频道接受消息。
        package main
    
        import (
            "github.com/garyburd/redigo/redis"
            "fmt"
            "time"
        )
    
        func Subs() {  //订阅者
            conn, err := redis.Dial("tcp", "10.1.210.69:6379")
            if err != nil {
                fmt.Println("connect redis error :", err)
                return
            }
            defer conn.Close()
            psc := redis.PubSubConn{conn}
            psc.Subscribe("channel1") //订阅channel1频道
            for {
                switch v := psc.Receive().(type) {
                case redis.Message:
                    fmt.Printf("%s: message: %s
    ", v.Channel, v.Data)
                case redis.Subscription:
                    fmt.Printf("%s: %s %d
    ", v.Channel, v.Kind, v.Count)
                case error:
                    fmt.Println(v)
                    return
                }
            }
        }
    
        func Push(message string)  { //发布者
            conn, _ := redis.Dial("tcp", "10.1.210.69:6379")
            _,err1 := conn.Do("PUBLISH", "channel1", message)
            if err1 != nil {
                    fmt.Println("pub err: ", err1)
                        return
                    }
    
        }
    
        func main()  {
            go Subs()
            go Push("this is wd")
            time.Sleep(time.Second*3)
        }
    
        控制台打印结果:
        channel1: subscribe 1
        channel1: message: this is wd
    
    • 事务操作
    1. MULTI, EXEC,DISCARD和WATCH是构成Redis事务的基础,当然我们使用go语言对redis进行事务操作的时候本质也是使用这些命令。
    2. MULTI:开启事务
    3. EXEC:执行事务
    4. DISCARD:取消事务
    5. WATCH:监视事务中的键变化,一旦有改变则取消事务。
        package main
    
        import (
        "github.com/garyburd/redigo/redis"
        "fmt"
        )
    
    
        func main()  {
            conn,err := redis.Dial("tcp","10.1.210.69:6379")
            if err != nil {
                fmt.Println("connect redis error :",err)
                return
            }
            defer conn.Close()
            conn.Send("MULTI")
            conn.Send("INCR", "foo")
            conn.Send("INCR", "bar")
            r, err := conn.Do("EXEC")
            fmt.Println(r)
        }
    
        控制台打印结果:
        [1, 1]
    
  • 相关阅读:
    友元类和友元函数
    C++中构造函数和析构函数调用的时机
    Linux 下svn恢复到某一版本
    lua 中pairs 和 ipairs区别
    孤儿进程与僵尸进程
    union
    关于C++ const 的全面总结
    后台管理左侧菜单
    全选-反选-取消
    Dom-直接 /间接选择器
  • 原文地址:https://www.cnblogs.com/KylinBlog/p/13607407.html
Copyright © 2011-2022 走看看