golang mysql 全局_golang操作MySQL几个原则和示例

本文介绍了使用Golang操作MySQL的几个关键原则,包括利用库自带的连接池、正确设置MaxIdle和MaxOpen参数、避免长时间事务和未关闭的Prepare语句。同时,提供了初始化连接、查询、更新和预处理语句的示例代码,强调了时间字段的正确配置以及底层已经实现的重试机制。
摘要由CSDN通过智能技术生成

使用原则

库自带连接池,使用方不需自行实现。*sql.DB 线程安全,开箱即用,屏弊了底层创建连接的实现

Open 只是创建类,调用一次即可,使用前需要 Ping 确保连接正常。

一定要设置连接池的两个参数 MaxIdle, MaxOpen,否则在极端情况会把 DB 连接打满(未加索引,大事务阻塞)。可选 MaxLifetime,需咨询 DBA,一般 DB 默认8小时,无需设置,如果很短要视情况而定

事务会占用一个连接,尽可能减小事务耗时,打散大事务,否则会将 DB 连接数打满

prepare 会占用一个连接,每次使用完后,一定要 close ,否则同样会将连接数打满

DSN 需要指定时区和对时间字段的支持,否则会出现时间提前8小时的问题

Query, Prepare, Exec 无需业务层重试,底层已经实现

下一篇源码走读会详细说明原因

连接创建示例

type MySQLClient struct {

Host string

MaxIdle int

MaxOpen int

User string

Pwd string

DB string

Port int

pool *sql.DB

}

func (mc *MySQLClient) Init() (err error) {

// 构建 DSN 时尤其注意 loc 和 parseTime 正确设置

// 东八区,允许解析时间字段

uri := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&loc=%s&parseTime=true",

mc.User,

mc.Pwd,

mc.Host,

mc.Port,

mc.DB,

url.QueryEscape("Asia/Shanghai"))

// Open 全局一个实例只需调用一次

mc.pool, err = sql.Open("mysql", uri)

if err != nil {

return err

}

//使用前 Ping, 确保 DB 连接正常

err = mc.pool.Ping()

if err != nil {

return err

}

// 设置最大连接数,一定要设置 MaxOpen

mc.pool.SetMaxIdleConns(mc.MaxIdle)

mc.pool.SetMaxOpenConns(mc.MaxOpen)

return nil

}

数据库查询示例

func testQuery(beginTime, endTime, code string) ([]*OrderInfo, error) {

db := iowrapper.MySQLClient.GetMySQL()

err := db.Ping()

if err != nil {

return nil, err

}

var rows *sql.Rows

// sql 可以用占位符,涉及业务分表提前生成

rows, err = db.Query(getSqlByCode(code, beginTime, endTime))

if err != nil {

return nil, err

}

OrderInfos := make([]*OrderInfo, 0, 10)

for rows.Next() {

oi := &OrderInfo{}

var createTime time.Time

err := rows.Scan(&oi.OrderId, &createTime, &oi.StartingLng, &oi.StartingLat, &oi.DestLng, &oi.DestLat)

if err != nil {

continue

}

oi.CreateTime = createTime.Unix()

OrderInfos = append(OrderInfos, oi)

}

return OrderInfos, nil

}

数据库更新示例

func testExec() error {

sql := "update test.table1 set _create_time=now() where id=?"

res, err := db.Exec(sql, 7988161482)

if err != nil {

fmt.Println("exec error ", err.Error())

return err

}

fmt.Println(res.LastInsertId())

fmt.Println(res.RowsAffected())

return nil

}

数据库prepare示例

func testStmt() error {

//占位符sql

sql := "update test.table1 set _create_time=now() where id=?"

stmt, err := db.Prepare(sql)

if err != nil {

fmt.Println("stmt error ", err.Error())

return err

}

// 一定要关闭,很重要

defer stmt.Close()

// 可以批量,示例只有一个

_, err = stmt.Exec(7988161474)

if err != nil {

fmt.Println("stmt exec error ", err.Error())

return err

}

return nil

}

有疑问加站长微信联系(非本文作者)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值