diff --git a/g/database/gdb/gdb.go b/g/database/gdb/gdb.go index d209be590..1a09d1d39 100644 --- a/g/database/gdb/gdb.go +++ b/g/database/gdb/gdb.go @@ -34,11 +34,12 @@ type DB interface { // 建立数据库连接方法(开发者一般不需要直接调用) Open(config *ConfigNode) (*sql.DB, error) - // SQL操作方法 + // SQL操作方法 API Query(query string, args ...interface{}) (*sql.Rows, error) Exec(sql string, args ...interface{}) (sql.Result, error) Prepare(sql string, execOnMaster...bool) (*sql.Stmt, error) + // 内部实现API的方法(不同数据库可覆盖这些方法实现自定义的操作) doQuery(link dbLink, query string, args ...interface{}) (rows *sql.Rows, err error) doExec(link dbLink, query string, args ...interface{}) (result sql.Result, err error) doPrepare(link dbLink, query string) (*sql.Stmt, error) @@ -85,6 +86,7 @@ type DB interface { // 设置管理 SetDebug(debug bool) + SetSchema(schema string) GetQueriedSqls() []*Sql PrintQueriedSqls() SetMaxIdleConns(n int) @@ -114,7 +116,8 @@ type dbBase struct { debug *gtype.Bool // (默认关闭)是否开启调试模式,当开启时会启用一些调试特性 sqls *gring.Ring // (debug=true时有效)已执行的SQL列表 cache *gcache.Cache // 数据库缓存,包括底层连接池对象缓存及查询缓存;需要注意的是,事务查询不支持查询缓存 - maxIdleConnCount *gtype.Int // 连接池最大限制的连接数 + schema *gtype.String // 手动切换的数据库名称 + maxIdleConnCount *gtype.Int // 连接池最大限制的连接数 maxOpenConnCount *gtype.Int // 连接池最大打开的连接数 maxConnLifetime *gtype.Int // (单位秒)连接对象可重复使用的时间长度 } @@ -162,6 +165,7 @@ func New(groupName ...string) (db DB, err error) { group : group, debug : gtype.NewBool(), cache : gcache.New(), + schema : gtype.NewString(), maxIdleConnCount : gtype.NewInt(), maxOpenConnCount : gtype.NewInt(), maxConnLifetime : gtype.NewInt(), @@ -265,11 +269,6 @@ func (bs *dbBase) getSqlDb(master bool) (sqlDb *sql.DB, err error) { if err != nil { return nil, err } - // 检查缓存连接池对象 - cacheKey := node.String() - if v := bs.cache.Get(cacheKey); v != nil { - return v.(*sql.DB), nil - } v := bs.cache.GetOrSetFuncLock(node.String(), func() interface{} { sqlDb, err = bs.db.Open(node) if err != nil { @@ -298,9 +297,18 @@ func (bs *dbBase) getSqlDb(master bool) (sqlDb *sql.DB, err error) { if v != nil && sqlDb == nil { sqlDb = v.(*sql.DB) } + // 是否手动选择数据库 + if v := bs.schema.Val(); v != "" { + sqlDb.Exec("USE " + v) + } return } +// 切换操作的数据库(注意该切换是全局的) +func (bs *dbBase) SetSchema(schema string) { + bs.schema.Set(schema) +} + // 创建底层数据库master链接对象 func (bs *dbBase) Master() (*sql.DB, error) { return bs.getSqlDb(true) diff --git a/g/database/gdb/gdb_model.go b/g/database/gdb/gdb_model.go index 64a6c8ab9..3ff09a849 100644 --- a/g/database/gdb/gdb_model.go +++ b/g/database/gdb/gdb_model.go @@ -452,22 +452,23 @@ func (md *Model) Count() (int, error) { } // 查询操作,对底层SQL操作的封装 -func (md *Model) getAll(sql string, args ...interface{}) (result Result, err error) { - var cacheKey string +func (md *Model) getAll(query string, args ...interface{}) (result Result, err error) { + cacheKey := "" // 查询缓存查询处理 if md.cacheEnabled { cacheKey = md.cacheName if len(cacheKey) == 0 { - cacheKey = sql + "/" + gconv.String(args) + cacheKey = query + "/" + gconv.String(args) } if v := md.db.getCache().Get(cacheKey); v != nil { return v.(Result), nil } } + if md.tx == nil { - result, err = md.db.GetAll(sql, args...) + result, err = md.db.GetAll(query, args...) } else { - result, err = md.tx.GetAll(sql, args...) + result, err = md.tx.GetAll(query, args...) } // 查询缓存保存处理 if len(cacheKey) > 0 && err == nil { diff --git a/g/database/gdb/gdb_unit_0_test.go b/g/database/gdb/gdb_unit_0_test.go new file mode 100644 index 000000000..0cf8bdb10 --- /dev/null +++ b/g/database/gdb/gdb_unit_0_test.go @@ -0,0 +1,52 @@ +package gdb_test + +import ( + "gitee.com/johng/gf/g/database/gdb" + "gitee.com/johng/gf/g/util/gtest" +) + +var ( + // 数据库对象/接口 + db gdb.DB +) + +// 初始化连接参数。 +// 测试前需要修改连接参数。 +func init() { + gdb.AddDefaultConfigNode(gdb.ConfigNode{ + Host: "127.0.0.1", + Port: "3306", + User: "root", + Pass: "12345678", + Name: "", + Type: "mysql", + Role: "master", + Charset: "utf8", + Priority: 1, + }) + if r, err := gdb.New(); err != nil { + gtest.Fatal(err) + } else { + db = r + } + // 准备测试数据结构 + if _, err := db.Exec("CREATE DATABASE IF NOT EXISTS `test` CHARACTER SET UTF8"); err != nil { + gtest.Fatal(err) + } + db.SetSchema("test") + if _, err := db.Exec("DROP TABLE `user`"); err != nil { + gtest.Fatal(err) + } + if _, err := db.Exec(` + CREATE TABLE user ( + id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID', + passport varchar(45) NOT NULL COMMENT '账号', + password char(32) NOT NULL COMMENT '密码', + nickname varchar(45) NOT NULL COMMENT '昵称', + create_time timestamp NOT NULL COMMENT '创建时间/注册时间', + PRIMARY KEY (id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `); err != nil { + gtest.Fatal(err) + } +} diff --git a/g/database/gdb/gdb_unit_1_test.go b/g/database/gdb/gdb_unit_1_test.go index bf132375c..8e3bd979f 100644 --- a/g/database/gdb/gdb_unit_1_test.go +++ b/g/database/gdb/gdb_unit_1_test.go @@ -2,57 +2,11 @@ package gdb_test import ( "gitee.com/johng/gf/g" - "gitee.com/johng/gf/g/database/gdb" "gitee.com/johng/gf/g/os/gtime" "gitee.com/johng/gf/g/util/gtest" "testing" ) -var ( - // 数据库对象/接口 - db gdb.DB -) - -// 初始化连接参数。 -// 测试前需要修改连接参数。 -func init() { - gdb.AddDefaultConfigNode(gdb.ConfigNode{ - Host: "127.0.0.1", - Port: "3306", - User: "root", - Pass: "", - Name: "test", - Type: "mysql", - Role: "master", - Charset: "utf8", - Priority: 1, - }) - if r, err := gdb.New(); err != nil { - gtest.Fatal(err) - } else { - db = r - } - // 准备测试数据结构 - if _, err := db.Exec("CREATE DATABASE IF NOT EXISTS `test` CHARACTER SET UTF8"); err != nil { - gtest.Fatal(err) - } - if _, err := db.Exec("DROP TABLE `user`"); err != nil { - gtest.Fatal(err) - } - if _, err := db.Exec(` - CREATE TABLE user ( - id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID', - passport varchar(45) NOT NULL COMMENT '账号', - password char(32) NOT NULL COMMENT '密码', - nickname varchar(45) NOT NULL COMMENT '昵称', - create_time timestamp NOT NULL COMMENT '创建时间/注册时间', - PRIMARY KEY (id) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - `); err != nil { - gtest.Fatal(err) - } -} - func TestDbBase_Query(t *testing.T) { if _, err := db.Query("SELECT ?", 1); err != nil { gtest.Fatal(err) diff --git a/g/os/grpool/grpool_bench_1_test.go b/g/os/grpool/grpool_bench_1_test.go index 16826af47..9b58e3ece 100644 --- a/g/os/grpool/grpool_bench_1_test.go +++ b/g/os/grpool/grpool_bench_1_test.go @@ -13,18 +13,18 @@ import ( "gitee.com/johng/gf/g/os/grpool" ) -func increment1() { +func increment() { for i := 0; i < 1000000; i++ {} } func BenchmarkGrpool_1(b *testing.B) { for i := 0; i < b.N; i++ { - grpool.Add(increment1) + grpool.Add(increment) } } func BenchmarkGoroutine_1(b *testing.B) { for i := 0; i < b.N; i++ { - go increment1() + go increment() } } \ No newline at end of file diff --git a/g/os/grpool/grpool_bench2_test.go b/g/os/grpool/grpool_bench_2_test.go similarity index 91% rename from g/os/grpool/grpool_bench2_test.go rename to g/os/grpool/grpool_bench_2_test.go index 0c47175bd..7f301309a 100644 --- a/g/os/grpool/grpool_bench2_test.go +++ b/g/os/grpool/grpool_bench_2_test.go @@ -15,10 +15,6 @@ import ( var n = 500000 -func increment2() { - for i := 0; i < 1000000; i++ {} -} - func BenchmarkGrpool2(b *testing.B) { b.N = n for i := 0; i < b.N; i++ {