From 3d54b01867b41ecc8bd5a063796bc0b9306ed288 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 27 Apr 2018 13:59:02 +0800 Subject: [PATCH] =?UTF-8?q?gdb=E5=A2=9E=E5=8A=A0=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E8=BF=9E=E6=8E=A5=E6=B1=A0=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb.go | 51 +++++++++++++++++++++++++++++++++---------- geg/other/test.go | 3 +++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/g/database/gdb/gdb.go b/g/database/gdb/gdb.go index 25d47f249..017990a78 100644 --- a/g/database/gdb/gdb.go +++ b/g/database/gdb/gdb.go @@ -15,6 +15,8 @@ import ( "gitee.com/johng/gf/g/util/grand" _ "github.com/lib/pq" _ "github.com/go-sql-driver/mysql" + "sync" + "gitee.com/johng/gf/g/container/gmap" ) const ( @@ -95,6 +97,15 @@ type Map map[string]interface{} // 关联数组列表(索引从0开始的数组),绑定多条记录 type List []Map +// MySQL接口对象 +var linkMysql = &dbmysql{} + +// PostgreSQL接口对象 +var linkPgsql = &dbpgsql{} + +// 二级数据库连接池,这是一个临时的对象池,键名为对应的单节点数据库配置,键值为*sync.Pool +var dbPools = gmap.NewStringInterfaceMap() + // 使用默认/指定分组配置进行连接,数据库集群配置项:default func New(groupName...string) (*Db, error) { name := config.d @@ -170,21 +181,15 @@ func getConfigNodeByPriority (cg ConfigGroup) *ConfigNode { func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) { var link Link switch masterNode.Type { - case "mysql": link = Link(&dbmysql{}) - case "pgsql": link = Link(&dbpgsql{}) + case "mysql": link = linkMysql + case "pgsql": link = linkPgsql default: return nil, errors.New(fmt.Sprintf("unsupported db type '%s'", masterNode.Type)) } - master, err := link.Open(masterNode) - if err != nil { - return nil, err - } - slave := master + master := openDb(link, masterNode) + slave := master if slaveNode != nil { - slave, err = link.Open(slaveNode) - if err != nil { - return nil, err - } + slave = openDb(link, slaveNode) } return &Db { link : link, @@ -195,6 +200,30 @@ func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) { }, nil } +func openDb (link Link, node *ConfigNode) *sql.DB { + var pool *sync.Pool + poolKey := fmt.Sprintf("%v", *node) + if v := dbPools.Get(poolKey); v == nil { + pool := sync.Pool{ + New : func() interface{} { + if db, err := link.Open(node); err != nil { + //glog.Error(err) + return nil + } else { + return db + } + }, + } + dbPools.Set(poolKey, pool) + } else { + pool = v.(*sync.Pool) + } + if v := pool.Get(); v != nil { + return v.(*sql.DB) + } + return nil +} + // 将结果列表按照指定的字段值做map[string]Map func (list List) ToStringMap(key string) map[string]Map { m := make(map[string]Map) diff --git a/geg/other/test.go b/geg/other/test.go index 5aa12c1dc..aeb1e5efd 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -3,9 +3,12 @@ package main import ( "fmt" "math/rand" + "sync" ) func main() { + p := &sync.Pool{} + p.Put() for i := 0; i < 100; i++ { fmt.Println(rand.Intn(200)) }