Go--连接DB

 mysql

下载依赖包

go get -u github.com/go-sql-driver/mysql

 

复制代码
package main

import (
    "database/sql"
    "fmt"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

func ConnectMysql() *sql.DB {
    dataSourceName := user + ":" + password + "@tcp(" + host + ":" + port + ")/" + database + "?charset=utf8&parseTime=True"
    conn, err := sql.Open("mysql", dataSourceName)
    if err != nil {
        return nil
    }
    conn.SetConnMaxLifetime(time.Minute * 30) // 最大连接超时时间,应小于数据库本身的链接超时时间
    conn.SetMaxIdleConns(10)                  // 最大闲置连接数(并发时可以同时获取的连接,也是用完后放回池里面的互用的连接, 从而提升性能)
    conn.SetMaxOpenConns(100)                 // 最大打开连接数,0为不限制

    // 记得结束后关闭连接
    defer conn.Close()

    // 验证连接池是否可以,使用ping初始化一个连接
    err = conn.Ping()
    if err != nil {
        fmt.Println("database init failed, err: , err")
        return nil
    }

    /*简单查询
      row := conn.QueryRow("select * from table_name")
      var str string
      row.Scan(&str)
      fmt.Println(str)
      **/

    return conn
}
复制代码

 

redis

下载依赖包

go get -u github.com/go-redis/redis

 

复制代码
func ConnRedis() *redis.Client {
    rd := redis.NewClient(&redis.Options{
        // 连接信息
        Network:  "tcp",                 // 网络类型:tcp,unix 默认tcp
        Addr:     "127.0.0.1:9736",      // 单机连接
        Password: "",                    // 密码
        DB:       0,                     // 数据库,默认0

        // 连接池容量及闲置连接数量
        PoolSize:     8,  // 连接池最大socket数,默认为4倍cpu核数
        MinIdleConns: 10, // 启动阶段创建指定数量的idle连接,并长期维持idle状态的连接数不少于指定数量

        // 超时
        DialTimeout:  5 * time.Second, // 连接建立超时时间,默认5秒
        ReadTimeout:  5 * time.Second, // 读超时时间,默认3秒,-1表示取消读超时
        WriteTimeout: 5 * time.Second, // 写超时时间,默认等于读超时
        PoolTimeout:  5 * time.Second, // 当所有连接都处在繁忙状态时,客户端等待可用连接的最大等待时长,默认读超时+1秒

        // 闲置连接检查
        IdleCheckFrequency: 60 * time.Second, // 闲置连接检查的周期,默认为1分钟,-1表示不作周期性检查,只在客户端获取连接时对闲置连接进行处理
        IdleTimeout:        5 * time.Minute,  // 闲置超时,默认5分钟,-1表示取消闲置超时检查
        MaxConnAge:         0 * time.Second,  // 连接存活时长,从创建开始计时,超过指定时长则关闭连接,默认为0,即不关闭存活时长较长的连接

        // 命令执行失败时的重试策略
        MaxRetries:      0,                      // 命令执行失败时,最多重试多少次,默认为0,即不重试
        MinRetryBackoff: 8 * time.Millisecond,   // 每次计算重试间隔时间的下限,默认8毫秒,-1表示取消间隔
        MaxRetryBackoff: 512 * time.Millisecond, // 每次计算重试间隔时间的上限,默认512毫秒,-1表示取消间隔

        // 可自定义连接函数
        Dialer: func() (net.Conn, error) {
            netDialer := &net.Dialer{
                Timeout:   5 * time.Second,
                KeepAlive: 5 * time.Second,
            }
            return netDialer.Dial("tcp", "127.0.0.1:6379")
        },

        // 钩子函数
        OnConnect: func(conn *redis.Conn) error { // 仅当客户端执行命令需要从连接池获取连接时,且连接池需要新建连接时,才会调用此函数
            fmt.Printf("conn=%v\n", conn)
            return nil
        },
    })

    // 集群模式连接
    /*rd := redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{"rec-ops-dev.cn-s01-dgdev01.redis.oppo.dev:6379"},
    })/**/

    // 哨兵模式连接
    /*rd := redis.NewFailoverClient(&redis.FailoverOptions{
        MasterName: "name",
        SentinelAddrs: []string{"10.x.x.x:9736","10.x.x.x:9736"},
    })/**/

    defer rd.Close() // 记得关闭连接

    result, err := rd.Ping().Result()
    if err != nil {
        fmt.Println("ping err:", err)
        return nil
    }
    fmt.Println(result)

    return rd
}
复制代码

实例:

复制代码
package main

import (
    "errors"
    "fmt"
    "github.com/go-redis/redis"
    "time"
)

func ConnRedis() {
    rd := redis.NewClient(&redis.Options{
        Addr:     "127.0.0.1:9736",       // 单机连接
        Password: "123",                  // 密码
        DB:       0,                     // 数据库
    })

    result, err := rd.Ping().Result()
    if err != nil {
        fmt.Println("ping err:", err)
        return
    }
    fmt.Println(result)

    // 新建一个key-value,第三个参数为过期时间(0为不过期)
    err = rd.Set("k1", "v1", 3*time.Second).Err()
    if err != nil {
        fmt.Println("set err:", err)
        return
    }

    // 获取key-value
    val, err := rd.Get("k1").Result()
    if err != nil {
        // 如果返回的错误是key不存在
        if errors.Is(err, redis.Nil) { // go-redis 库提供了一个 redis.Nil 错误来表示 Key 不存在的错误,以此区别处理 redis.Nil 和其他不为 nil 的错误
            fmt.Println("key error:", nil)
            return
        }
        // 其他错误
        fmt.Println(err)
        return
    } else { // 打印value
        fmt.Println("k1 == ", val)
    }

    // 程序等待5秒钟
    time.Sleep(5 * time.Second)

    v2, err := rd.Get("k1").Result()
    if err != nil {
        // 如果返回的错误是key不存在
        if errors.Is(err, redis.Nil) {
            fmt.Println("key error:", nil)
            return
        }
        // 其他错误
        fmt.Println(err)
        return
    } else {
        fmt.Println("k1 == ", v2)
    }
}

func main() {
    ConnRedis()
}
复制代码

 

clickhouse

下载依赖包

go get -u  github.com/ClickHouse/clickhouse-go/v2

连接

复制代码
package main

import (
    "database/sql"
    "errors"
    "fmt"
    "github.com/ClickHouse/clickhouse-go/v2"
    "time"
)

func main() {
    // 连接ck
    username := "sre"
    host := "127.0.0.1"
    port := "9001"
    password := "123"
    database := "sre"
    clickHouseConn := clickhouse.OpenDB(&clickhouse.Options{
        Addr: []string{host + ":" + port},
        Auth: clickhouse.Auth{
            Database: database,
            Username: username,
            Password: password,
        },
        Settings: clickhouse.Settings{
            "max_execution_time": 1800, // 设置执行查询操作的最长时间,超过将终止查询,单位:秒;有助于防止长时间运行的查询占用过多资源,从而影响系统的性能和响应能力
        },
        DialTimeout: 10 * time.Second, //建立连接的最长时间。默认为1s
        Compression: &clickhouse.Compression{ // 指定数据在存储或传输时的压缩方式,通过设置压缩方法,可以在存储数据时减少所需的空间。这对于存储大型数据集非常有用,可以显著降低存储成本和提高 I/O 性能
            Method: clickhouse.CompressionLZ4, // 使用LZ4算法进行压缩,LZ4 算法以其快速的压缩和解压缩速度著称,适合需要快速读写操作的场景;ZSTD:提供较高的压缩比,适合对存储效率要求较高的场景;None:不压缩
        },
        Debug: false,
    })

    // 延迟关闭连接池
    defer clickHouseConn.Close()

    // 定义变量
    var name string
    // 单行查询
    row := clickHouseConn.QueryRow("select name from t1 where psa_id=?", 1212)
    // 数据映射,将结果映射到变量中
    if err := row.Scan(&name); errors.Is(err, sql.ErrNoRows) { // 判断查询结果是不是空集
        fmt.Println("The query result is empty")
    } else if err != nil { // 查询异常
        fmt.Println("Query failed", err)
    } else { // 查询正常且有值
        fmt.Println("Query was successful")
    }
    // 打印结果
    fmt.Println(name)
}
复制代码

 

参数参照官网:https://clickhouse.com/docs/en/integrations/go#connecting

 

posted @   心恩惠动  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示