diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index 91f111eea..cbc8a4c9a 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -422,7 +422,13 @@ func (c *Core) DoInsert(link Link, table string, data interface{}, option int, b switch reflectKind { case reflect.Slice, reflect.Array: return c.DB.DoBatchInsert(link, table, data, option, batch...) - case reflect.Map, reflect.Struct: + case reflect.Struct: + if _, ok := data.(apiInterfaces); ok { + return c.DB.DoBatchInsert(link, table, data, option, batch...) + } else { + dataMap = DataToMapDeep(data) + } + case reflect.Map: dataMap = DataToMapDeep(data) default: return result, errors.New(fmt.Sprint("unsupported data type:", reflectKind)) diff --git a/database/gdb/gdb_func.go b/database/gdb/gdb_func.go index 3dd45bc8e..ff6ed45b8 100644 --- a/database/gdb/gdb_func.go +++ b/database/gdb/gdb_func.go @@ -104,7 +104,6 @@ func DataToMapDeep(value interface{}) map[string]interface{} { if v, ok := value.(apiMapStrAny); ok { return v.MapStrAny() } - var ( rvValue reflect.Value rvField reflect.Value diff --git a/database/gdb/gdb_z_mysql_model_test.go b/database/gdb/gdb_z_mysql_model_test.go index 0e2c87df4..4fedc49d6 100644 --- a/database/gdb/gdb_z_mysql_model_test.go +++ b/database/gdb/gdb_z_mysql_model_test.go @@ -94,7 +94,30 @@ func Test_Model_Insert(t *testing.T) { n, _ = result.RowsAffected() t.Assert(n, 3) }) +} +func Test_Model_BatchInsertWithArrayStruct(t *testing.T) { + table := createTable() + defer dropTable(table) + gtest.C(t, func(t *gtest.T) { + user := db.Table(table) + array := garray.New() + for i := 1; i <= SIZE; i++ { + array.Append(g.Map{ + "id": i, + "uid": i, + "passport": fmt.Sprintf("t%d", i), + "password": "25d55ad283aa400af464c76d713c07ad", + "nickname": fmt.Sprintf("name_%d", i), + "create_time": gtime.Now().String(), + }) + } + + result, err := user.Filter().Data(array).Insert() + t.Assert(err, nil) + n, _ := result.LastInsertId() + t.Assert(n, SIZE) + }) } func Test_Model_InsertIgnore(t *testing.T) {