From 2c7fb178b3493cab6c81f1498be6acee71e206d4 Mon Sep 17 00:00:00 2001 From: zhenghaorong Date: Sat, 3 Sep 2022 16:09:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3append=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E9=94=99=E4=B9=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chain.go | 136 ++++++++++++++++++++++++++++++------------ transaction_chain.go | 137 +++++++++++++++++++++++++++++++------------ 2 files changed, 197 insertions(+), 76 deletions(-) diff --git a/chain.go b/chain.go index 9b0afd1..969db52 100644 --- a/chain.go +++ b/chain.go @@ -357,40 +357,67 @@ func (this *Query) UpdateAllStmt() error { dbName := getTableName(this.dbname, this.table) var sql string - var dataSql = []string{} - var valSql = []string{} - var updSql = []string{} - var updFieldLen = len(this.upd_field) - if len(this.save_data) > 0 { + var dataSql []string //一组用到的占位字符 + var valSql []string //占位字符组 + var updSql []string //更新字段的sql + var updFieldLen = len(this.upd_field) //需要更新的字段数量,为0时更新除id外添加值 + dataLen := len(this.save_data) + if dataLen > 0 { //批量操作 - this.data = []string{} - this.value = []interface{}{} - for i, datum := range this.save_data { + this.data = this.data[0:0] + this.value = this.value[0:0] + var dataSqlText string //占位字符组 + for i := 0; i < dataLen; i++ { if i == 0 { - for k, _ := range datum { - this.data = append(this.data, k) - dataSql = append(dataSql, "?") - if updFieldLen == 0 && k != "id" { - updSql = append(updSql, k+"=values("+k+")") + //第一组时分配变量空间 + fieldLen := len(this.save_data[i]) + this.data = make([]string, 0, fieldLen) + dataSql = make([]string, 0, fieldLen) + this.value = make([]interface{}, 0, fieldLen*dataLen) + valSql = make([]string, 0, dataLen) + switch updFieldLen { + case 0: + //预览创建数据的长度 + updSql = make([]string, 0, fieldLen) + default: + //按照需要更新字段数长度 + updSql = make([]string, 0, updFieldLen) + for _, k := range this.upd_field { + updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段 } } - if updFieldLen > 0 { - for _, k := range this.upd_field { - updSql = append(updSql, k+"=values("+k+")") + for k := range this.save_data[i] { + this.data = append(this.data, k) //存储添加的字段 + dataSql = append(dataSql, "?") //存储需要的占位符 + if updFieldLen == 0 && k != "id" { + updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段 } } + dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式 } - for _, k := range this.data { - this.value = append(this.value, datum[k]) + for j := 0; j < len(this.data); j++ { + this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值 } - valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") + valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组 } } else { - //添加一条 - for _, datum := range this.data { + //添加一条(原理同上) + fieldLen := len(this.data) + dataSql = make([]string, 0, fieldLen) + valSql = make([]string, 0, 1) + switch updFieldLen { + case 0: + updSql = make([]string, 0, fieldLen) + default: + updSql = make([]string, 0, updFieldLen) + for _, k := range this.upd_field { + updSql = append(updSql, k+"=values("+k+")") + } + } + for i := 0; i < fieldLen; i++ { dataSql = append(dataSql, "?") - if updFieldLen == 0 && datum != "id" { - updSql = append(updSql, datum+"=values("+datum+")") + if updFieldLen == 0 && this.data[i] != "id" { + updSql = append(updSql, this.data[i]+"=values("+this.data[i]+")") } } if updFieldLen > 0 { @@ -402,7 +429,7 @@ func (this *Query) UpdateAllStmt() error { } if len(this.data) == 0 { - return errors.New("参数错误,没有数据表") + return errors.New("参数错误,没有字段值") } if len(this.value) == 0 { return errors.New("参数错误,条件值错误") @@ -417,7 +444,16 @@ func (this *Query) UpdateAllStmt() error { if this.debug { log.Println("insert on duplicate key update sql:", sql, this.value) } + conditionLen := 0 //所有条件数 + for _, ch2 := range sql { + if string(ch2) == "?" { + conditionLen++ + } + } + if conditionLen != len(this.value) { + return errors.New("参数错误,条件值数量不匹配") + } if this.conn == nil { this.conn = DB } @@ -443,28 +479,41 @@ func (this *Query) CreateAllStmt() error { dbName := getTableName(this.dbname, this.table) var sql string - var dataSql = []string{} - var valSql = []string{} - - if len(this.save_data) > 0 { - this.data = []string{} - this.value = []interface{}{} - for i, datum := range this.save_data { + var dataSql []string //一组用到的占位字符 + var valSql []string //占位字符组 + dataLen := len(this.save_data) + if dataLen > 0 { + //清空字段和值 + this.data = this.data[0:0] + this.value = this.value[0:0] + var dataSqlText string //占位字符组 + for i := 0; i < dataLen; i++ { if i == 0 { - for k, _ := range datum { - this.data = append(this.data, k) - dataSql = append(dataSql, "?") + //第一组时分配变量空间 + fieldLen := len(this.save_data[i]) + this.data = make([]string, 0, fieldLen) + dataSql = make([]string, 0, fieldLen) + this.value = make([]interface{}, 0, fieldLen*dataLen) + valSql = make([]string, 0, dataLen) + for k := range this.save_data[i] { + this.data = append(this.data, k) //存储字段 + dataSql = append(dataSql, "?") //存储需要的占位符 } + dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式 } - for _, k := range this.data { - this.value = append(this.value, datum[k]) + for j := 0; j < len(this.data); j++ { + this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值 } - valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") + valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组 } } else { - for i := 0; i < len(this.data); i++ { + //添加一条(原理同上) + fieldLen := len(this.data) + dataSql = make([]string, 0, fieldLen) + for i := 0; i < fieldLen; i++ { dataSql = append(dataSql, "?") } + valSql = make([]string, 0, 1) valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") } @@ -474,7 +523,7 @@ func (this *Query) CreateAllStmt() error { if len(this.value) == 0 { return errors.New("参数错误,条件值错误") } - + //通过sql关键字优化批量操作和单个操作效率 setText := " values " if len(valSql) > 1 { setText = " value " @@ -484,7 +533,16 @@ func (this *Query) CreateAllStmt() error { if this.debug { log.Println("insert sql:", sql, this.value) } + conditionLen := 0 //所有条件数 + for _, ch2 := range sql { + if string(ch2) == "?" { + conditionLen++ + } + } + if conditionLen != len(this.value) { + return errors.New("参数错误,条件值数量不匹配") + } if this.conn == nil { this.conn = DB } diff --git a/transaction_chain.go b/transaction_chain.go index 561c282..0cd3e6c 100644 --- a/transaction_chain.go +++ b/transaction_chain.go @@ -353,38 +353,67 @@ func (this *TxQuery) UpdateAllStmt() error { dbName := getTableName(this.dbname, this.table) var sql string - var dataSql = []string{} - var valSql = []string{} - var updSql = []string{} - var updFieldLen = len(this.upd_field) - if len(this.save_data) > 0 { - this.data = []string{} - this.value = []interface{}{} - for i, datum := range this.save_data { + var dataSql []string //一组用到的占位字符 + var valSql []string //占位字符组 + var updSql []string //更新字段的sql + var updFieldLen = len(this.upd_field) //需要更新的字段数量,为0时更新除id外添加值 + dataLen := len(this.save_data) + if dataLen > 0 { + //批量操作 + this.data = this.data[0:0] + this.value = this.value[0:0] + var dataSqlText string //占位字符组 + for i := 0; i < dataLen; i++ { if i == 0 { - for k, _ := range datum { - this.data = append(this.data, k) - dataSql = append(dataSql, "?") - if updFieldLen == 0 && k != "id" { - updSql = append(updSql, k+"=values("+k+")") + //第一组时分配变量空间 + fieldLen := len(this.save_data[i]) + this.data = make([]string, 0, fieldLen) + dataSql = make([]string, 0, fieldLen) + this.value = make([]interface{}, 0, fieldLen*dataLen) + valSql = make([]string, 0, dataLen) + switch updFieldLen { + case 0: + //预览创建数据的长度 + updSql = make([]string, 0, fieldLen) + default: + //按照需要更新字段数长度 + updSql = make([]string, 0, updFieldLen) + for _, k := range this.upd_field { + updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段 } } - if updFieldLen > 0 { - for _, k := range this.upd_field { - updSql = append(updSql, k+"=values("+k+")") + for k := range this.save_data[i] { + this.data = append(this.data, k) //存储添加的字段 + dataSql = append(dataSql, "?") //存储需要的占位符 + if updFieldLen == 0 && k != "id" { + updSql = append(updSql, k+"=values("+k+")") //存储需要更新的字段 } } + dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式 } - for _, k := range this.data { - this.value = append(this.value, datum[k]) + for j := 0; j < len(this.data); j++ { + this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值 } - valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") + valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组 } } else { - for _, datum := range this.data { + //添加一条(原理同上) + fieldLen := len(this.data) + dataSql = make([]string, 0, fieldLen) + valSql = make([]string, 0, 1) + switch updFieldLen { + case 0: + updSql = make([]string, 0, fieldLen) + default: + updSql = make([]string, 0, updFieldLen) + for _, k := range this.upd_field { + updSql = append(updSql, k+"=values("+k+")") + } + } + for i := 0; i < fieldLen; i++ { dataSql = append(dataSql, "?") - if updFieldLen == 0 && datum != "id" { - updSql = append(updSql, datum+"=values("+datum+")") + if updFieldLen == 0 && this.data[i] != "id" { + updSql = append(updSql, this.data[i]+"=values("+this.data[i]+")") } } if updFieldLen > 0 { @@ -396,7 +425,7 @@ func (this *TxQuery) UpdateAllStmt() error { } if len(this.data) == 0 { - return errors.New("参数错误,没有数据表") + return errors.New("参数错误,没有字段值") } if len(this.value) == 0 { return errors.New("参数错误,条件值错误") @@ -410,7 +439,16 @@ func (this *TxQuery) UpdateAllStmt() error { if this.debug { log.Println("insert on duplicate key update sql:", sql, this.value) } + conditionLen := 0 //所有条件数 + for _, ch2 := range sql { + if string(ch2) == "?" { + conditionLen++ + } + } + if conditionLen != len(this.value) { + return errors.New("参数错误,条件值数量不匹配") + } stmt, err = this.tx.Prepare(sql) if err != nil { @@ -471,27 +509,41 @@ func (this *TxQuery) CreateAllStmt() error { dbName := getTableName(this.dbname, this.table) var sql string - var dataSql = []string{} - var valSql = []string{} - if len(this.save_data) > 0 { - this.data = []string{} - this.value = []interface{}{} - for i, datum := range this.save_data { + var dataSql []string //一组用到的占位字符 + var valSql []string //占位字符组 + dataLen := len(this.save_data) + if dataLen > 0 { + //清空字段和值 + this.data = this.data[0:0] + this.value = this.value[0:0] + var dataSqlText string //占位字符组 + for i := 0; i < dataLen; i++ { if i == 0 { - for k, _ := range datum { - this.data = append(this.data, k) - dataSql = append(dataSql, "?") + //第一组时分配变量空间 + fieldLen := len(this.save_data[i]) + this.data = make([]string, 0, fieldLen) + dataSql = make([]string, 0, fieldLen) + this.value = make([]interface{}, 0, fieldLen*dataLen) + valSql = make([]string, 0, dataLen) + for k := range this.save_data[i] { + this.data = append(this.data, k) //存储字段 + dataSql = append(dataSql, "?") //存储需要的占位符 } + dataSqlText = strings.Join(dataSql, ",") //组成每组占位字符格式 } - for _, k := range this.data { - this.value = append(this.value, datum[k]) + for j := 0; j < len(this.data); j++ { + this.value = append(this.value, this.save_data[i][this.data[j]]) //存储值 } - valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") + valSql = append(valSql, "("+dataSqlText+")") //组成占位字符组 } } else { - for i := 0; i < len(this.data); i++ { + //添加一条(原理同上) + fieldLen := len(this.data) + dataSql = make([]string, 0, fieldLen) + for i := 0; i < fieldLen; i++ { dataSql = append(dataSql, "?") } + valSql = make([]string, 0, 1) valSql = append(valSql, "("+strings.Join(dataSql, " , ")+")") } @@ -501,6 +553,7 @@ func (this *TxQuery) CreateAllStmt() error { if len(this.value) == 0 { return errors.New("参数错误,条件值错误") } + //通过sql关键字优化批量操作和单个操作效率 setText := " values " if len(valSql) > 1 { setText = " value " @@ -513,6 +566,16 @@ func (this *TxQuery) CreateAllStmt() error { if this.debug { log.Println("insert sql:", sql, this.value) } + conditionLen := 0 //所有条件数 + + for _, ch2 := range sql { + if string(ch2) == "?" { + conditionLen++ + } + } + if conditionLen != len(this.value) { + return errors.New("参数错误,条件值数量不匹配") + } stmt, err = this.tx.Prepare(sql) @@ -621,7 +684,7 @@ func (this *TxQuery) Update() (int64, error) { return StmtForUpdateExec(this.stmt, this.value) } -//批量更新 +// UpdateAll 批量更新(根据唯一键判断存在则更新,不存在则创建) func (this *TxQuery) UpdateAll() (int64, error) { err := this.UpdateAllStmt()