From 3330a417a9c6bc2d8c6f15d4641415bcd475d3e9 Mon Sep 17 00:00:00 2001 From: Michael Yang Date: Fri, 2 Feb 2024 11:52:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Db.insertBatchWithFirstRowColumns=20?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=85=85=E4=B8=BB?= =?UTF-8?q?=E9=94=AE=E5=AD=97=E6=AE=B5=20close=20#273?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/provider/RowSqlProvider.java | 10 +- .../java/com/mybatisflex/core/row/Row.java | 33 +++-- .../java/com/mybatisflex/core/row/RowCPI.java | 4 +- .../java/com/mybatisflex/test/DbTest.java | 29 +--- .../java/com/mybatisflex/test/DbTest273.java | 130 ++++++++++++++++++ .../src/main/resources/data273.sql | 4 + .../src/main/resources/schema.sql | 2 +- .../src/main/resources/schema_273.sql | 12 ++ 8 files changed, 177 insertions(+), 47 deletions(-) create mode 100644 mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest273.java create mode 100644 mybatis-flex-test/mybatis-flex-native-test/src/main/resources/data273.sql create mode 100644 mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema_273.sql diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java index f0fcec31..0eae2fb4 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java @@ -27,7 +27,6 @@ import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.util.ArrayUtil; import com.mybatisflex.core.util.ClassUtil; -import org.apache.ibatis.javassist.util.proxy.ProxyObject; import java.util.*; @@ -70,7 +69,7 @@ public class RowSqlProvider { // 先生成 SQL,再设置参数 String sql = DialectFactory.getDialect().forInsertRow(schema, tableName, row); - ProviderUtil.setSqlArgs(params, row.obtainInsertValues(null)); + ProviderUtil.setSqlArgs(params, row.obtainInsertValues()); return sql; } @@ -91,8 +90,7 @@ public class RowSqlProvider { // 让所有 row 的列顺序和值的数量与第条数据保持一致 // 这个必须 new 一个 LinkedHashSet,因为 keepModifyAttrs 会清除 row 所有的 modifyAttrs - Set modifyAttrs = new LinkedHashSet<>(RowCPI.getModifyAttrs(rows.get(0))); - rows.forEach(row -> row.keep(modifyAttrs)); + Set modifyAttrs = new LinkedHashSet<>(RowCPI.getInsertAttrs(rows.get(0))); //sql: INSERT INTO `tb_table`(`name`, `sex`) VALUES (?, ?),(?, ?),(?, ?) String sql = DialectFactory.getDialect().forInsertBatchWithFirstRowColumns(schema, tableName, rows); @@ -178,7 +176,7 @@ public class RowSqlProvider { String tableName = ProviderUtil.getTableName(params); Row row = ProviderUtil.getRow(params); String sql = DialectFactory.getDialect().forUpdateById(schema, tableName, row); - ProviderUtil.setSqlArgs(params, RowCPI.obtainAllModifyValues(row)); + ProviderUtil.setSqlArgs(params, RowCPI.obtainUpdateValues(row)); return sql; } @@ -228,7 +226,7 @@ public class RowSqlProvider { Object[] values = FlexConsts.EMPTY_ARRAY; for (Row row : rows) { - values = ArrayUtil.concat(values, RowCPI.obtainAllModifyValues(row)); + values = ArrayUtil.concat(values, RowCPI.obtainUpdateValues(row)); } ProviderUtil.setSqlArgs(params, values); return sql; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java index 2cbf5050..82b9b334 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java @@ -546,27 +546,28 @@ public class Row extends LinkedHashMap implements UpdateWrapper< } - Object[] obtainAllModifyValues() { + /** + * 获取更新的数据,主键后置 + * + * @return 数据内容 + */ + Object[] obtainUpdateValues() { return ArrayUtil.concat(obtainModifyValuesWithoutPk(), obtainsPrimaryValues()); } - public Object[] obtainInsertValues(Set withAttrs) { + public Object[] obtainInsertValues() { List values = new ArrayList<>(); - if (withAttrs == null || withAttrs.isEmpty()) { - withAttrs = keySet(); - - if (primaryKeys != null && !primaryKeys.isEmpty()) { - for (RowKey primaryKey : primaryKeys) { - if (primaryKey.before) { - values.add(get(primaryKey.keyColumn)); - } + if (primaryKeys != null && !primaryKeys.isEmpty()) { + for (RowKey primaryKey : primaryKeys) { + if (primaryKey.before) { + values.add(get(primaryKey.keyColumn)); } } } - for (String key : withAttrs) { + for (String key : keySet()) { Object value = get(key); if (!isPk(key) && !(value instanceof RawValue)) { values.add(value); @@ -576,6 +577,16 @@ public class Row extends LinkedHashMap implements UpdateWrapper< return values.toArray(); } + public Object[] obtainInsertValues(Set withAttrs) { + List values = new ArrayList<>(); + for (String key : withAttrs) { + Object value = get(key); + values.add(value); + } + return values.toArray(); + } + + public Set getInsertAttrs() { Set attrs = new LinkedHashSet<>(); if (primaryKeys != null && !primaryKeys.isEmpty()) { diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowCPI.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowCPI.java index 3cbcaea7..2d021dec 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowCPI.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowCPI.java @@ -49,8 +49,8 @@ public class RowCPI { return row.obtainsPrimaryValues(); } - public static Object[] obtainAllModifyValues(Row row) { - return row.obtainAllModifyValues(); + public static Object[] obtainUpdateValues(Row row) { + return row.obtainUpdateValues(); } public static Set getModifyAttrs(Row row) { diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest.java index 1b30625e..d0b29a19 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest.java @@ -21,7 +21,9 @@ import com.mybatisflex.core.audit.AuditManager; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.row.Db; import com.mybatisflex.core.row.Row; +import com.mybatisflex.core.row.RowKey; import com.mybatisflex.core.row.RowUtil; +import com.mybatisflex.core.update.RawValue; import com.mybatisflex.core.update.UpdateWrapper; import com.mybatisflex.core.util.UpdateEntity; import org.apache.ibatis.session.Configuration; @@ -108,31 +110,4 @@ public class DbTest { } } - - @Test - public void testDbInsertBatchWithFirstRowColumns() { - List rows = new ArrayList<>(); - - Row row1 = new Row(); - row1.put("id", 111); - row1.put("user_name", "张三"); - row1.put("age", 20); - rows.add(row1); - - Row row2 = new Row(); - row2.put("age", 30); - row2.put("id", 20); - row2.put("user_name", "李四"); - rows.add(row2); - - Db.insertBatchWithFirstRowColumns("tb_account", rows); - - Row row3= new Row(); - row3.put("age", 30); - row3.put("id", 333); - row3.put("user_name", "李四3"); - Db.insert("tb_account",row3); - - RowUtil.printPretty(Db.selectAll("tb_account")); - } } diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest273.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest273.java new file mode 100644 index 00000000..d60f16de --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTest273.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.test; + +import com.mybatisflex.core.MybatisFlexBootstrap; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.Db; +import com.mybatisflex.core.row.Row; +import com.mybatisflex.core.row.RowKey; +import com.mybatisflex.core.row.RowUtil; +import com.mybatisflex.core.update.RawValue; +import com.mybatisflex.core.update.UpdateWrapper; +import com.mybatisflex.core.util.UpdateEntity; +import org.apache.ibatis.session.Configuration; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author 王帅 + * @since 2023-10-11 + */ +public class DbTest273 { + + @BeforeClass + public static void init() { + DataSource dataSource = new EmbeddedDatabaseBuilder() + .setType(EmbeddedDatabaseType.H2) + .addScript("schema_273.sql") + .addScript("data273.sql") + .build(); + + MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance() + .setDataSource(dataSource) + .start(); + + /* + * 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法, + * 这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等) + * 是不能设置成 null 的。 + */ + Configuration configuration = bootstrap.getConfiguration(); + configuration.setCallSettersOnNulls(true); + + Db.updateBySql("update tb_account set options = null;"); + } + + @SuppressWarnings("all") + static String tb_account = "tb_account"; + + + + /** + * https://github.com/mybatis-flex/mybatis-flex/issues/273 + */ + @Test + public void testDbInsertBatchWithFirstRowColumns() { + List rows = new ArrayList<>(); + + Row row1 = new Row(); + row1.put("id", 111); + row1.put("user_name", "张三"); + row1.put("age", 20); + rows.add(row1); + + Row row2 = new Row(); + row2.put("age", 30); + row2.put("id", 20); + row2.put("user_name", "李四"); + rows.add(row2); + + Db.insertBatchWithFirstRowColumns("tb_account", rows); + + Row row3= new Row(); + row3.put("age", 30); + row3.put("id", 333); + row3.put("user_name", "李四3"); + Db.insert("tb_account",row3); + + RowUtil.printPretty(Db.selectAll("tb_account")); + } + + /** + * https://github.com/mybatis-flex/mybatis-flex/issues/273 + */ + @Test + public void testDbInsertBatchWithFirstRowColumns02() { + List rows = new ArrayList<>(); + + Row row1 = Row.ofKey(RowKey.SNOW_FLAKE_ID); + row1.put("user_name", "张三"); + row1.put("age", 20); + rows.add(row1); + + Row row2 = Row.ofKey(RowKey.SNOW_FLAKE_ID); + row2.put("age", 30); + row2.put("user_name", "李四"); + rows.add(row2); + +// Row row3 = Row.ofKey(RowKey.SNOW_FLAKE_ID); +// row3.put("age", new RawValue(11)); +// row3.put("user_name", "李四3"); +// rows.add(row3); + + Db.insertBatchWithFirstRowColumns("tb_account", rows); + + RowUtil.printPretty(Db.selectAll("tb_account")); + } +} diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/data273.sql b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/data273.sql new file mode 100644 index 00000000..61e295d0 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/data273.sql @@ -0,0 +1,4 @@ +INSERT INTO tb_account +VALUES (1, '张三', 18, 0,'2020-01-11', '{"key":"value1"}',0), + (2, '王麻子叔叔', 19, 1, '2021-03-21', '{"key":"value2"}',0); + diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema.sql b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema.sql index 0ec83316..b1e0d57f 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema.sql +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema.sql @@ -17,4 +17,4 @@ CREATE TABLE IF NOT EXISTS `tb_article` `title` VARCHAR(100), `content` text, `is_delete` Integer -); \ No newline at end of file +); diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema_273.sql b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema_273.sql new file mode 100644 index 00000000..2e476020 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/resources/schema_273.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS `tb_account` +( + `id` VARCHAR(100), + `user_name` VARCHAR(100), + `age` Integer, + `sex` Integer, + `birthday` DATETIME, + `options` VARCHAR(1024), + `is_delete` Integer +); + +