From 209de2c3ed67096887520db338ba2047934227e1 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 8 Jan 2018 14:15:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9Bgdb=E9=93=BE=E5=BC=8F?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=EF=BC=8CREADME=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/database/gdb/gdb.go | 8 +- g/database/gdb/gdb_base.go | 27 +++-- g/database/gdb/gdb_linkop.go | 110 ++++++++---------- g/os/gcache/gcache.go | 3 +- geg/database/mysql/mysql.go | 63 +++++++++- .../mvc/controller/demo/object_method.go | 5 +- 6 files changed, 128 insertions(+), 88 deletions(-) diff --git a/g/database/gdb/gdb.go b/g/database/gdb/gdb.go index 48fcbcd82..379fa42c9 100644 --- a/g/database/gdb/gdb.go +++ b/g/database/gdb/gdb.go @@ -60,10 +60,10 @@ type Link interface { Replace(table string, data Map) (sql.Result, error) Save(table string, data Map) (sql.Result, error) - batchInsert(table string, list List, batch int, option uint8) error - BatchInsert(table string, list List, batch int) error - BatchReplace(table string, list List, batch int) error - BatchSave(table string, list List, batch int) error + batchInsert(table string, list List, batch int, option uint8) (sql.Result, error) + BatchInsert(table string, list List, batch int) (sql.Result, error) + BatchReplace(table string, list List, batch int) (sql.Result, error) + BatchSave(table string, list List, batch int) (sql.Result, error) Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) diff --git a/g/database/gdb/gdb_base.go b/g/database/gdb/gdb_base.go index b053dd441..85eba7c70 100644 --- a/g/database/gdb/gdb_base.go +++ b/g/database/gdb/gdb_base.go @@ -241,15 +241,16 @@ func (l *dbLink) Save(table string, data Map) (sql.Result, error) { } // 批量写入数据 -func (l *dbLink) batchInsert(table string, list List, batch int, option uint8) error { +func (l *dbLink) batchInsert(table string, list List, batch int, option uint8) (sql.Result, error) { var keys []string var values []string var bvalues []string var params []interface{} - var size int = len(list) + var result sql.Result + var size = len(list) // 判断长度 if size < 1 { - return errors.New("empty data list") + return result, errors.New("empty data list") } // 首先获取字段名称及记录长度 for k, _ := range list[0] { @@ -274,35 +275,37 @@ func (l *dbLink) batchInsert(table string, list List, batch int, option uint8) e } bvalues = append(bvalues, "(" + strings.Join(values, ",") + ")") if len(bvalues) == batch { - _, err := l.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, l.charl, table, l.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + r, err := l.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, l.charl, table, l.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) if err != nil { - return err + return result, err } + result = r bvalues = bvalues[:0] } } // 处理最后不构成指定批量的数据 - if (len(bvalues) > 0) { - _, err := l.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, l.charl, table, l.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) + if len(bvalues) > 0 { + r, err := l.Exec(fmt.Sprintf("%s INTO %s%s%s(%s) VALUES%s %s", operation, l.charl, table, l.charr, kstr, strings.Join(bvalues, ","), updatestr), params...) if err != nil { - return err + return result, err } + result = r } - return nil + return result, nil } // CURD操作:批量数据指定批次量写入 -func (l *dbLink) BatchInsert(table string, list List, batch int) error { +func (l *dbLink) BatchInsert(table string, list List, batch int) (sql.Result, error) { return l.link.batchInsert(table, list, batch, OPTION_INSERT) } // CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么删除后重新写入一条 -func (l *dbLink) BatchReplace(table string, list List, batch int) error { +func (l *dbLink) BatchReplace(table string, list List, batch int) (sql.Result, error) { return l.link.batchInsert(table, list, batch, OPTION_REPLACE) } // CURD操作:批量数据指定批次量写入, 如果数据存在(主键或者唯一索引),那么更新,否则写入一条新数据 -func (l *dbLink) BatchSave(table string, list List, batch int) error { +func (l *dbLink) BatchSave(table string, list List, batch int) (sql.Result, error) { return l.link.batchInsert(table, list, batch, OPTION_SAVE) } diff --git a/g/database/gdb/gdb_linkop.go b/g/database/gdb/gdb_linkop.go index 8e18917cd..926874acb 100644 --- a/g/database/gdb/gdb_linkop.go +++ b/g/database/gdb/gdb_linkop.go @@ -15,18 +15,17 @@ import ( // 数据库链式操作对象 type gLinkOp struct { - link Link - tables string - fields string - condition string - conditionArgs []interface{} - groupby string - orderby string - start int - limit int - data interface{} - dataList List - batch int + link Link // 数据库链接对象 + tables string // 数据库操作表 + fields string // 操作字段 + condition string // 操作条件 + conditionArgs []interface{} // 操作条件参数 + groupby string // 分组语句 + orderby string // 排序语句 + start int // 分页开始 + limit int // 分页条数 + data interface{} // 操作记录(支持Map/List/string类型) + batch int // 批量操作条数 } // 链式操作,数据表字段,可支持多个表,以半角逗号连接 @@ -93,14 +92,17 @@ func (op *gLinkOp) Data(data interface{}) (*gLinkOp) { return op } -// 链式操作,操作数据记录项列表 -func (op *gLinkOp) List(list List) (*gLinkOp) { - op.dataList = list - return op -} - -// 链式操作, CURD - Insert +// 链式操作, CURD - Insert/BatchInsert func (op *gLinkOp) Insert() (sql.Result, error) { + // 批量操作 + if list, ok := op.data.(List); ok { + batch := 10 + if op.batch > 0 { + batch = op.batch + } + return op.link.BatchInsert(op.tables, list, batch) + } + // 记录操作 if op.data == nil { return nil, errors.New("inserting into table with empty data") } @@ -110,8 +112,17 @@ func (op *gLinkOp) Insert() (sql.Result, error) { return nil, errors.New("inserting into table with invalid data type") } -// 链式操作, CURD - Replace +// 链式操作, CURD - Replace/BatchReplace func (op *gLinkOp) Replace() (sql.Result, error) { + // 批量操作 + if list, ok := op.data.(List); ok { + batch := 10 + if op.batch > 0 { + batch = op.batch + } + return op.link.BatchReplace(op.tables, list, batch) + } + // 记录操作 if op.data == nil { return nil, errors.New("replacing into table with empty data") } @@ -121,8 +132,17 @@ func (op *gLinkOp) Replace() (sql.Result, error) { return nil, errors.New("replacing into table with invalid data type") } -// 链式操作, CURD - Save +// 链式操作, CURD - Save/BatchSave func (op *gLinkOp) Save() (sql.Result, error) { + // 批量操作 + if list, ok := op.data.(List); ok { + batch := 10 + if op.batch > 0 { + batch = op.batch + } + return op.link.BatchSave(op.tables, list, batch) + } + // 记录操作 if op.data == nil { return nil, errors.New("saving into table with empty data") } @@ -132,48 +152,6 @@ func (op *gLinkOp) Save() (sql.Result, error) { return nil, errors.New("saving into table with invalid data type") } -// 设置批处理的大小 -func (op *gLinkOp) Batch(batch int) *gLinkOp { - op.batch = batch - return op -} - -// 链式操作, CURD - BatchInsert -func (op *gLinkOp) BatchInsert() error { - if op.dataList == nil || len(op.dataList) < 1 { - return errors.New("batch inserting into table with empty data list") - } - batch := 10 - if op.batch > 0 { - batch = op.batch - } - return op.link.BatchInsert(op.tables, op.dataList, batch) -} - -// 链式操作, CURD - BatchReplace -func (op *gLinkOp) BatchReplace() error { - if op.dataList == nil || len(op.dataList) < 1 { - return errors.New("batch replacing into table with empty data list") - } - batch := 10 - if op.batch > 0 { - batch = op.batch - } - return op.link.BatchReplace(op.tables, op.dataList, batch) -} - -// 链式操作, CURD - BatchSave -func (op *gLinkOp) BatchSave() error { - if op.dataList == nil || len(op.dataList) < 1 { - return errors.New("batch saving into table with empty data list") - } - batch := 10 - if op.batch > 0 { - batch = op.batch - } - return op.link.BatchSave(op.tables, op.dataList, batch) -} - // 链式操作, CURD - Update func (op *gLinkOp) Update() (sql.Result, error) { if op.data == nil { @@ -190,6 +168,12 @@ func (op *gLinkOp) Delete() (sql.Result, error) { return op.link.Delete(op.tables, op.condition, op.conditionArgs...) } +// 设置批处理的大小 +func (op *gLinkOp) Batch(batch int) *gLinkOp { + op.batch = batch + return op +} + // 链式操作,select func (op *gLinkOp) Select() (List, error) { if op.fields == "" { diff --git a/g/os/gcache/gcache.go b/g/os/gcache/gcache.go index b5116b394..7c3c12e40 100644 --- a/g/os/gcache/gcache.go +++ b/g/os/gcache/gcache.go @@ -4,7 +4,8 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. -// 单进程缓存 +// 单进程缓存. +// @todo 需要新增一个MAP,用于时间与过期键值对的快速处理。 package gcache import ( diff --git a/geg/database/mysql/mysql.go b/geg/database/mysql/mysql.go index 6b63b64bf..f247749cf 100644 --- a/geg/database/mysql/mysql.go +++ b/geg/database/mysql/mysql.go @@ -3,7 +3,6 @@ package main import ( "fmt" "time" - "strconv" "gitee.com/johng/gf/g/database/gdb" ) @@ -198,11 +197,11 @@ func save() { // 批量写入 func batchInsert() { fmt.Println("batchInsert:") - err := db.BatchInsert("user", gdb.List { - {"name": "john_" + strconv.FormatInt(time.Now().UnixNano(), 10)}, - {"name": "john_" + strconv.FormatInt(time.Now().UnixNano(), 10)}, - {"name": "john_" + strconv.FormatInt(time.Now().UnixNano(), 10)}, - {"name": "john_" + strconv.FormatInt(time.Now().UnixNano(), 10)}, + _, err := db.BatchInsert("user", gdb.List { + {"name": "john_1"}, + {"name": "john_2"}, + {"name": "john_3"}, + {"name": "john_4"}, }, 10) if err != nil { fmt.Println(err) @@ -322,6 +321,58 @@ func linkopUpdate3() { fmt.Println() } + +// 链式批量写入 +func linkopBatchInsert1() { + fmt.Println("linkopBatchInsert1:") + r, err := db.Table("user").Data(gdb.List{ + {"name": "john_1"}, + {"name": "john_2"}, + {"name": "john_3"}, + {"name": "john_4"}, + }).Insert() + if (err == nil) { + fmt.Println(r.RowsAffected()) + } else { + fmt.Println(err) + } + fmt.Println() +} + +// 链式批量写入,指定每批次写入的条数 +func linkopBatchInsert2() { + fmt.Println("linkopBatchInsert2:") + r, err := db.Table("user").Data(gdb.List{ + {"name": "john_1"}, + {"name": "john_2"}, + {"name": "john_3"}, + {"name": "john_4"}, + }).Batch(2).Insert() + if (err == nil) { + fmt.Println(r.RowsAffected()) + } else { + fmt.Println(err) + } + fmt.Println() +} + +// 链式批量保存 +func linkopBatchSave() { + fmt.Println("linkopBatchSave:") + r, err := db.Table("user").Data(gdb.List{ + {"id":1, "name": "john_1"}, + {"id":2, "name": "john_2"}, + {"id":3, "name": "john_3"}, + {"id":4, "name": "john_4"}, + }).Save() + if (err == nil) { + fmt.Println(r.RowsAffected()) + } else { + fmt.Println(err) + } + fmt.Println() +} + // 主从io复用测试,在mysql中使用 show full processlist 查看链接信息 func keepPing() { fmt.Println("keepPing:") diff --git a/geg/frame/mvc/controller/demo/object_method.go b/geg/frame/mvc/controller/demo/object_method.go index 1d2941651..6aa4ce602 100644 --- a/geg/frame/mvc/controller/demo/object_method.go +++ b/geg/frame/mvc/controller/demo/object_method.go @@ -7,8 +7,9 @@ import ( type ObjectMethod struct {} func init() { - ghttp.GetServer().BindObjectMethod("/object-method", &ObjectMethod{}, "Show1, Show2, Show3") - ghttp.GetServer().Domain("localhost").BindObjectMethod("/object-method", &ObjectMethod{}, "Show4") + obj := &ObjectMethod{} + ghttp.GetServer().BindObjectMethod("/object-method", obj, "Show1, Show2, Show3") + ghttp.GetServer().Domain("localhost").BindObjectMethod("/object-method", obj, "Show4") } func (o *ObjectMethod) Show1(r *ghttp.Request) {