fix: Db.insertBatchWithFirstRowColumns 不能自动填充主键字段 close #273

This commit is contained in:
Michael Yang 2024-02-02 11:52:03 +08:00
parent 7cd79889ae
commit 3330a417a9
8 changed files with 177 additions and 47 deletions

View File

@ -27,7 +27,6 @@ import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ArrayUtil; import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.ClassUtil; import com.mybatisflex.core.util.ClassUtil;
import org.apache.ibatis.javassist.util.proxy.ProxyObject;
import java.util.*; import java.util.*;
@ -70,7 +69,7 @@ public class RowSqlProvider {
// 先生成 SQL再设置参数 // 先生成 SQL再设置参数
String sql = DialectFactory.getDialect().forInsertRow(schema, tableName, row); String sql = DialectFactory.getDialect().forInsertRow(schema, tableName, row);
ProviderUtil.setSqlArgs(params, row.obtainInsertValues(null)); ProviderUtil.setSqlArgs(params, row.obtainInsertValues());
return sql; return sql;
} }
@ -91,8 +90,7 @@ public class RowSqlProvider {
// 让所有 row 的列顺序和值的数量与第条数据保持一致 // 让所有 row 的列顺序和值的数量与第条数据保持一致
// 这个必须 new 一个 LinkedHashSet因为 keepModifyAttrs 会清除 row 所有的 modifyAttrs // 这个必须 new 一个 LinkedHashSet因为 keepModifyAttrs 会清除 row 所有的 modifyAttrs
Set<String> modifyAttrs = new LinkedHashSet<>(RowCPI.getModifyAttrs(rows.get(0))); Set<String> modifyAttrs = new LinkedHashSet<>(RowCPI.getInsertAttrs(rows.get(0)));
rows.forEach(row -> row.keep(modifyAttrs));
//sql: INSERT INTO `tb_table`(`name`, `sex`) VALUES (?, ?),(?, ?),(?, ?) //sql: INSERT INTO `tb_table`(`name`, `sex`) VALUES (?, ?),(?, ?),(?, ?)
String sql = DialectFactory.getDialect().forInsertBatchWithFirstRowColumns(schema, tableName, rows); String sql = DialectFactory.getDialect().forInsertBatchWithFirstRowColumns(schema, tableName, rows);
@ -178,7 +176,7 @@ public class RowSqlProvider {
String tableName = ProviderUtil.getTableName(params); String tableName = ProviderUtil.getTableName(params);
Row row = ProviderUtil.getRow(params); Row row = ProviderUtil.getRow(params);
String sql = DialectFactory.getDialect().forUpdateById(schema, tableName, row); String sql = DialectFactory.getDialect().forUpdateById(schema, tableName, row);
ProviderUtil.setSqlArgs(params, RowCPI.obtainAllModifyValues(row)); ProviderUtil.setSqlArgs(params, RowCPI.obtainUpdateValues(row));
return sql; return sql;
} }
@ -228,7 +226,7 @@ public class RowSqlProvider {
Object[] values = FlexConsts.EMPTY_ARRAY; Object[] values = FlexConsts.EMPTY_ARRAY;
for (Row row : rows) { for (Row row : rows) {
values = ArrayUtil.concat(values, RowCPI.obtainAllModifyValues(row)); values = ArrayUtil.concat(values, RowCPI.obtainUpdateValues(row));
} }
ProviderUtil.setSqlArgs(params, values); ProviderUtil.setSqlArgs(params, values);
return sql; return sql;

View File

@ -546,27 +546,28 @@ public class Row extends LinkedHashMap<String, Object> implements UpdateWrapper<
} }
Object[] obtainAllModifyValues() { /**
* 获取更新的数据主键后置
*
* @return 数据内容
*/
Object[] obtainUpdateValues() {
return ArrayUtil.concat(obtainModifyValuesWithoutPk(), obtainsPrimaryValues()); return ArrayUtil.concat(obtainModifyValuesWithoutPk(), obtainsPrimaryValues());
} }
public Object[] obtainInsertValues(Set<String> withAttrs) { public Object[] obtainInsertValues() {
List<Object> values = new ArrayList<>(); List<Object> values = new ArrayList<>();
if (withAttrs == null || withAttrs.isEmpty()) { if (primaryKeys != null && !primaryKeys.isEmpty()) {
withAttrs = keySet(); for (RowKey primaryKey : primaryKeys) {
if (primaryKey.before) {
if (primaryKeys != null && !primaryKeys.isEmpty()) { values.add(get(primaryKey.keyColumn));
for (RowKey primaryKey : primaryKeys) {
if (primaryKey.before) {
values.add(get(primaryKey.keyColumn));
}
} }
} }
} }
for (String key : withAttrs) { for (String key : keySet()) {
Object value = get(key); Object value = get(key);
if (!isPk(key) && !(value instanceof RawValue)) { if (!isPk(key) && !(value instanceof RawValue)) {
values.add(value); values.add(value);
@ -576,6 +577,16 @@ public class Row extends LinkedHashMap<String, Object> implements UpdateWrapper<
return values.toArray(); return values.toArray();
} }
public Object[] obtainInsertValues(Set<String> withAttrs) {
List<Object> values = new ArrayList<>();
for (String key : withAttrs) {
Object value = get(key);
values.add(value);
}
return values.toArray();
}
public Set<String> getInsertAttrs() { public Set<String> getInsertAttrs() {
Set<String> attrs = new LinkedHashSet<>(); Set<String> attrs = new LinkedHashSet<>();
if (primaryKeys != null && !primaryKeys.isEmpty()) { if (primaryKeys != null && !primaryKeys.isEmpty()) {

View File

@ -49,8 +49,8 @@ public class RowCPI {
return row.obtainsPrimaryValues(); return row.obtainsPrimaryValues();
} }
public static Object[] obtainAllModifyValues(Row row) { public static Object[] obtainUpdateValues(Row row) {
return row.obtainAllModifyValues(); return row.obtainUpdateValues();
} }
public static Set<String> getModifyAttrs(Row row) { public static Set<String> getModifyAttrs(Row row) {

View File

@ -21,7 +21,9 @@ import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db; import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row; import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowKey;
import com.mybatisflex.core.row.RowUtil; import com.mybatisflex.core.row.RowUtil;
import com.mybatisflex.core.update.RawValue;
import com.mybatisflex.core.update.UpdateWrapper; import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.UpdateEntity; import com.mybatisflex.core.util.UpdateEntity;
import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.Configuration;
@ -108,31 +110,4 @@ public class DbTest {
} }
} }
@Test
public void testDbInsertBatchWithFirstRowColumns() {
List<Row> 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"));
}
} }

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 的时候是否调用映射对象的 settermap 对象时为 put方法
* 这在依赖于 Map.keySet() null 值进行初始化时比较有用注意基本类型intboolean
* 是不能设置成 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<Row> 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<Row> 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"));
}
}

View File

@ -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);

View File

@ -17,4 +17,4 @@ CREATE TABLE IF NOT EXISTS `tb_article`
`title` VARCHAR(100), `title` VARCHAR(100),
`content` text, `content` text,
`is_delete` Integer `is_delete` Integer
); );

View File

@ -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
);