first commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
// "context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MysqlConnector struct {
|
||||
}
|
||||
|
||||
func (c MysqlConnector) connect(config *DBConfig) *Connection {
|
||||
/**
|
||||
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
|
||||
// user@unix(/path/to/socket)/dbname
|
||||
// root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
|
||||
// user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
|
||||
// user:password@/dbname?sql_mode=TRADITIONAL
|
||||
// user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci
|
||||
// id:password@tcp(your-amazonaws-uri.com:3306)/dbname
|
||||
// user@cloudsql(project-id:instance-name)/dbname
|
||||
// user@cloudsql(project-id:regionname:instance-name)/dbname
|
||||
// user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
|
||||
// user:password@/dbname
|
||||
// user:password@/
|
||||
*/
|
||||
//TODO: Protocol loc readTimeout serverPubKey timeout
|
||||
if config.MaxOpenConns == 0 {
|
||||
config.MaxOpenConns = 15
|
||||
}
|
||||
if config.MaxIdleConns == 0 {
|
||||
config.MaxIdleConns = 5
|
||||
}
|
||||
if config.ConnMaxLifetime == 0 {
|
||||
config.ConnMaxLifetime = 86400
|
||||
}
|
||||
if config.ConnMaxIdleTime == 0 {
|
||||
config.ConnMaxIdleTime = 7200
|
||||
}
|
||||
var params []string
|
||||
|
||||
if len(config.Charset) > 0 {
|
||||
params = append(params, "charset="+config.Charset)
|
||||
}
|
||||
if len(config.Collation) > 0 {
|
||||
params = append(params, "collation="+config.Collation)
|
||||
}
|
||||
if config.MultiStatements {
|
||||
params = append(params, "multiStatements=true")
|
||||
}
|
||||
if config.ParseTime {
|
||||
params = append(params, "parseTime=true")
|
||||
}
|
||||
var dsn string
|
||||
if len(config.Dsn) > 0 {
|
||||
dsn = config.Dsn
|
||||
} else {
|
||||
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", config.Username, config.Password, config.Host, config.Port, config.Database, strings.Join(params, "&"))
|
||||
}
|
||||
db, err := sql.Open(DriverMysql, dsn)
|
||||
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
} else if err := db.Ping(); err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
// 最大链接数, 默认0, 不限制
|
||||
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||
// 最大空闲链接数, 默认2
|
||||
db.SetMaxIdleConns(config.MaxIdleConns)
|
||||
// 表示在连接池中连接的最大生存时间, 默认0, 表示不限制。
|
||||
db.SetConnMaxLifetime(time.Duration(config.ConnMaxLifetime) * time.Second)
|
||||
// 连接池中空闲连接的最大生存时间, 默认0, 表示不限制。
|
||||
db.SetConnMaxIdleTime(time.Duration(config.ConnMaxIdleTime) * time.Second)
|
||||
}
|
||||
|
||||
// 优化事物查询速度
|
||||
// Golang 在 MYSQL 事物中不能并发执行查询, 会出现 driver:bad connection,
|
||||
// 为了在事物中执行并发查询, 单独开一个脏读查询链接
|
||||
|
||||
// 处理 driver:bad connection, 需要加锁
|
||||
// 同一事务开启多协程的同时如果有并发读, 那可能会出现 driver:bad connection 错误,
|
||||
// 原因是同一事务同一时间只能有一个可以进行读操作, 读完之后需要将查询得到的Rows关闭.
|
||||
if len(params) > 0 {
|
||||
dsn = dsn + `&`
|
||||
}
|
||||
RxDB, err := sql.Open(DriverMysql, dsn+`transaction_isolation='read-uncommitted'`)
|
||||
if err != nil {
|
||||
panic("开启事物链接失败, " + err.Error())
|
||||
} else {
|
||||
RxDB.SetMaxOpenConns(5)
|
||||
RxDB.SetMaxIdleConns(5)
|
||||
}
|
||||
|
||||
return &Connection{
|
||||
RxDB: RxDB,
|
||||
DB: db,
|
||||
Config: config,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user