From 415bb8ef78b561ad5ba5b88dacdd69014adda895 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 6 Jun 2023 18:15:44 +0000 Subject: [PATCH 01/13] fix: upgrade com.alibaba:druid from 1.2.17 to 1.2.18 Snyk has created this PR to upgrade com.alibaba:druid from 1.2.17 to 1.2.18. See this package in Maven Repository: https://mvnrepository.com/artifact/com.alibaba/druid/ See this project in Snyk: https://app.snyk.io/org/z2z2qp/project/e0cf6b8b-62c9-4791-9b14-bfe183b2fc5b?utm_source=github&utm_medium=referral&page=upgrade-pr --- mybatis-flex-spring-boot-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mybatis-flex-spring-boot-starter/pom.xml b/mybatis-flex-spring-boot-starter/pom.xml index 28affc54..5f56b483 100644 --- a/mybatis-flex-spring-boot-starter/pom.xml +++ b/mybatis-flex-spring-boot-starter/pom.xml @@ -68,7 +68,7 @@ com.alibaba druid - 1.2.17 + 1.2.18 compile true From 6e1a30fb8e88067fd27f41917554b6821dedfb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E4=BD=B3=E5=BD=AC?= Date: Wed, 7 Jun 2023 09:53:19 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AAQuery?= =?UTF-8?q?Table=EF=BC=8C=E5=8F=82=E6=95=B0=E7=9A=84=E6=9E=84=E9=80=A0?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/mybatisflex/core/query/QueryColumn.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java index 708157e4..ec528cdf 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java @@ -54,6 +54,12 @@ public class QueryColumn implements Serializable { this.name = name; } + public QueryColumn(QueryTable queryTable, String name) { + SqlUtil.keepColumnSafely(name); + this.table = queryTable; + this.name = name; + } + public QueryTable getTable() { return table; From 7bcc8425b84e0879ab969c452e29856cc2e31fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Wed, 7 Jun 2023 11:59:40 +0800 Subject: [PATCH 03/13] fixed IllegalAccessException in EnjoyTemplate --- .../com/mybatisflex/codegen/template/impl/EnjoyTemplate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/template/impl/EnjoyTemplate.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/template/impl/EnjoyTemplate.java index 3ea8fbe4..cd1b43a8 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/template/impl/EnjoyTemplate.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/template/impl/EnjoyTemplate.java @@ -34,7 +34,7 @@ public class EnjoyTemplate implements ITemplate { public EnjoyTemplate() { engine = Engine.create("mybatis-flex", engine -> { - engine.addSharedMethod(StringUtil.class); + engine.addSharedStaticMethod(StringUtil.class); engine.setSourceFactory(new FileAndClassPathSourceFactory()); }); // 以下配置将支持 user.girl 表达式去调用 user 对象的 boolean isGirl() 方法 From 45e370e8554f740d010d567d31d667622c9bdc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Wed, 7 Jun 2023 16:36:54 +0800 Subject: [PATCH 04/13] update docs --- docs/zh/base/querywrapper.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/zh/base/querywrapper.md b/docs/zh/base/querywrapper.md index 2ccd998e..cc97ccf0 100644 --- a/docs/zh/base/querywrapper.md +++ b/docs/zh/base/querywrapper.md @@ -47,6 +47,10 @@ select * from tb_account where id >= 100 ``` +::: tip 问题:以上示例中,`ACCOUNT.ID.ge(100)` 中的 `ACCOUNT` 是怎么来的? +MyBatis-Flex 使用了 APT 技术,这个 `ACCOUNT` 是自动生成的。 +参考:《[MyBatis-Flex APT 配置](../others/apt.md)》章节。 +::: ## select * From d0a245869cfb969f4abac907dff77877e3493d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Wed, 7 Jun 2023 17:03:51 +0800 Subject: [PATCH 05/13] add "@Override" --- .../mybatisflex/codegen/generator/impl/ControllerGenerator.java | 2 ++ .../com/mybatisflex/codegen/generator/impl/EntityGenerator.java | 2 ++ .../com/mybatisflex/codegen/generator/impl/MapperGenerator.java | 2 ++ .../mybatisflex/codegen/generator/impl/MapperXmlGenerator.java | 2 ++ .../codegen/generator/impl/PackageInfoGenerator.java | 2 ++ .../mybatisflex/codegen/generator/impl/ServiceGenerator.java | 2 ++ .../codegen/generator/impl/ServiceImplGenerator.java | 2 ++ .../mybatisflex/codegen/generator/impl/TableDefGenerator.java | 2 ++ 8 files changed, 16 insertions(+) diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ControllerGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ControllerGenerator.java index 6ca56b6d..5c16ad6c 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ControllerGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ControllerGenerator.java @@ -73,10 +73,12 @@ public class ControllerGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, controllerJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/EntityGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/EntityGenerator.java index 71ab102a..25e97083 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/EntityGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/EntityGenerator.java @@ -73,10 +73,12 @@ public class EntityGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, entityJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperGenerator.java index 9e89fe9d..262114cf 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperGenerator.java @@ -73,10 +73,12 @@ public class MapperGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, mapperJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperXmlGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperXmlGenerator.java index c5667d13..88079706 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperXmlGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/MapperXmlGenerator.java @@ -70,10 +70,12 @@ public class MapperXmlGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, mapperXmlFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/PackageInfoGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/PackageInfoGenerator.java index 002ffb7d..d6c1fab1 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/PackageInfoGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/PackageInfoGenerator.java @@ -88,10 +88,12 @@ public class PackageInfoGenerator implements IGenerator { }); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceGenerator.java index bced18f0..aed26254 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceGenerator.java @@ -73,10 +73,12 @@ public class ServiceGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, serviceJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceImplGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceImplGenerator.java index 8c354b79..618311fb 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceImplGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/ServiceImplGenerator.java @@ -73,10 +73,12 @@ public class ServiceImplGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, serviceImplJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } diff --git a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/TableDefGenerator.java b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/TableDefGenerator.java index 9faafeaa..0398286d 100644 --- a/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/TableDefGenerator.java +++ b/mybatis-flex-codegen/src/main/java/com/mybatisflex/codegen/generator/impl/TableDefGenerator.java @@ -73,10 +73,12 @@ public class TableDefGenerator implements IGenerator { globalConfig.getTemplateConfig().getTemplate().generate(params, templatePath, tableDefJavaFile); } + @Override public String getTemplatePath() { return templatePath; } + @Override public void setTemplatePath(String templatePath) { this.templatePath = templatePath; } From d7c364c7eac0df6aa27fffe03475239feb4bdcd3 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Wed, 7 Jun 2023 18:16:33 +0000 Subject: [PATCH 06/13] fix: upgrade com.alibaba.fastjson2:fastjson2 from 2.0.31 to 2.0.32 Snyk has created this PR to upgrade com.alibaba.fastjson2:fastjson2 from 2.0.31 to 2.0.32. See this package in Maven Repository: https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2/ See this project in Snyk: https://app.snyk.io/org/z2z2qp/project/a2808ab6-77f3-4da1-a717-e26683b12111?utm_source=github&utm_medium=referral&page=upgrade-pr --- mybatis-flex-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mybatis-flex-core/pom.xml b/mybatis-flex-core/pom.xml index 836e8b05..d2c83778 100644 --- a/mybatis-flex-core/pom.xml +++ b/mybatis-flex-core/pom.xml @@ -49,7 +49,7 @@ com.alibaba.fastjson2 fastjson2 - 2.0.31 + 2.0.32 true compile From 9f3d3b5ab99a2a7d938d52c3add22d44ddcca254 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Wed, 7 Jun 2023 18:16:36 +0000 Subject: [PATCH 07/13] fix: upgrade com.alibaba:fastjson from 2.0.31 to 2.0.32 Snyk has created this PR to upgrade com.alibaba:fastjson from 2.0.31 to 2.0.32. See this package in Maven Repository: https://mvnrepository.com/artifact/com.alibaba/fastjson/ See this project in Snyk: https://app.snyk.io/org/z2z2qp/project/a2808ab6-77f3-4da1-a717-e26683b12111?utm_source=github&utm_medium=referral&page=upgrade-pr --- mybatis-flex-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mybatis-flex-core/pom.xml b/mybatis-flex-core/pom.xml index 836e8b05..65502066 100644 --- a/mybatis-flex-core/pom.xml +++ b/mybatis-flex-core/pom.xml @@ -41,7 +41,7 @@ com.alibaba fastjson - 2.0.31 + 2.0.32 true compile From b2fcb88ca8215f0b5145f2279b19083d4c27e4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 09:41:24 +0800 Subject: [PATCH 08/13] fixed: oracle insert batch error --- .../mybatisflex/core/dialect/IDialect.java | 2 +- .../core/dialect/impl/CommonsDialectImpl.java | 2 +- .../core/dialect/impl/OracleDialect.java | 92 ++++++++++++++++++- .../coretest/OracleDialectTester.java | 84 +++++++++++++++++ 4 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 mybatis-flex-core/src/test/java/com/mybatisflex/coretest/OracleDialectTester.java diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java index e7fcfa43..b31848f5 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java @@ -66,7 +66,7 @@ public interface IDialect { //////for entity ///// String forInsertEntity(TableInfo tableInfo, Object entity, boolean ignoreNulls); - String forInsertEntityBatch(TableInfo tableInfo, List entities); + String forInsertEntityBatch(TableInfo tableInfo, List entities); String forDeleteEntityById(TableInfo tableInfo); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java index 59d483d9..d7f21ec8 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java @@ -415,7 +415,7 @@ public class CommonsDialectImpl implements IDialect { } @Override - public String forInsertEntityBatch(TableInfo tableInfo, List entities) { + public String forInsertEntityBatch(TableInfo tableInfo, List entities) { StringBuilder sql = new StringBuilder(); sql.append("INSERT INTO ").append(tableInfo.getWrapSchemaAndTableName(this)); String[] insertColumns = tableInfo.obtainInsertColumns(null, false); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/OracleDialect.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/OracleDialect.java index b452148a..9b21f370 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/OracleDialect.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/OracleDialect.java @@ -17,9 +17,15 @@ package com.mybatisflex.core.dialect.impl; import com.mybatisflex.core.dialect.KeywordWrap; import com.mybatisflex.core.dialect.LimitOffsetProcessor; +import com.mybatisflex.core.row.Row; +import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.util.CollectionUtil; +import com.mybatisflex.core.util.StringUtil; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.StringJoiner; public class OracleDialect extends CommonsDialectImpl { @@ -56,8 +62,92 @@ public class OracleDialect extends CommonsDialectImpl { public OracleDialect() { this(LimitOffsetProcessor.ORACLE); } + public OracleDialect(LimitOffsetProcessor limitOffsetProcessor) { - super(new KeywordWrap(keywords,"\"","\""),limitOffsetProcessor); + super(new KeywordWrap(keywords, "\"", "\""), limitOffsetProcessor); } + @Override + public String forInsertEntityBatch(TableInfo tableInfo, List entities) { + /** + * INSERT ALL + * INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3') + * INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3') + * INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3') + * . + * . + * . + * SELECT 1 FROM DUAL; + */ + StringBuilder sql = new StringBuilder(); + sql.append("INSERT ALL"); + String[] insertColumns = tableInfo.obtainInsertColumns(null, false); + String[] warpedInsertColumns = new String[insertColumns.length]; + for (int i = 0; i < insertColumns.length; i++) { + warpedInsertColumns[i] = wrap(insertColumns[i]); + } + + + Map onInsertColumns = tableInfo.getOnInsertColumns(); + for (int i = 0; i < entities.size(); i++) { + sql.append(" INTO ").append(tableInfo.getWrapSchemaAndTableName(this)); + sql.append(" (").append(StringUtil.join(", ", warpedInsertColumns)).append(")"); + sql.append(" VALUES "); + + StringJoiner stringJoiner = new StringJoiner(", ", "(", ")"); + for (String insertColumn : insertColumns) { + if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) { + //直接读取 onInsert 配置的值,而不用 "?" 代替 + stringJoiner.add(onInsertColumns.get(insertColumn)); + } else { + stringJoiner.add("?"); + } + } + sql.append(stringJoiner); + } + + return sql.append(" SELECT 1 FROM DUAL").toString(); + } + + + @Override + public String forInsertBatchWithFirstRowColumns(String schema, String tableName, List rows) { + /** + * INSERT ALL + * INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3') + * INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3') + * INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3') + * . + * . + * . + * SELECT 1 FROM DUAL; + */ + StringBuilder fields = new StringBuilder(); + Row firstRow = rows.get(0); + Set attrs = firstRow.obtainModifyAttrs(); + int index = 0; + for (String column : attrs) { + fields.append(wrap(column)); + if (index != attrs.size() - 1) { + fields.append(", "); + } + index++; + } + + StringBuilder sql = new StringBuilder(); + sql.append("INSERT ALL"); + + String tableNameWrap = StringUtil.isNotBlank(schema) + ? wrap(getRealSchema(schema)) + "." + wrap(getRealTable(tableName)) + : wrap(getRealTable(tableName)); + String questionStrings = buildQuestion(attrs.size(), true); + + for (int i = 0; i < rows.size(); i++) { + sql.append(" INTO ").append(tableNameWrap); + sql.append(" (").append(fields).append(")"); + sql.append(" VALUES ").append(questionStrings); + } + + return sql.append(" SELECT 1 FROM DUAL").toString(); + } } diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/OracleDialectTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/OracleDialectTester.java new file mode 100644 index 00000000..e875716e --- /dev/null +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/OracleDialectTester.java @@ -0,0 +1,84 @@ +package com.mybatisflex.coretest; + +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.dialect.impl.OracleDialect; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.Row; +import com.mybatisflex.core.table.TableInfoFactory; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT; + +public class OracleDialectTester { + + + @Test + public void testSelectSql() { + QueryWrapper query = new QueryWrapper() + .select() + .from(ACCOUNT); + + IDialect dialect = new OracleDialect(); + String sql = dialect.forSelectByQuery(query); + System.out.println(sql); + } + + @Test + public void testInsertBatchSql() { + List accounts = new ArrayList<>(); + Account account1 = new Account(); + account1.setUserName("michael1"); + account1.setAge(18); + account1.setSex(1); + accounts.add(account1); + + Account account2 = new Account(); + account2.setUserName("michael2"); + account2.setAge(19); + account2.setSex(2); + accounts.add(account2); + + Account account3 = new Account(); + account3.setUserName("michael3"); + account3.setAge(20); + account3.setSex(3); + accounts.add(account3); + + + IDialect dialect = new OracleDialect(); + String sql = dialect.forInsertEntityBatch(TableInfoFactory.ofEntityClass(Account.class),accounts); + System.out.println(sql); + } + + + @Test + public void testInsertRowBatchSql() { + List accounts = new ArrayList<>(); + Row account1 = new Row(); + account1.set("username","michael1"); + account1.set("age",18); + account1.set("sex",1); + accounts.add(account1); + + Row account2 = new Row(); + account2.set("username","michael2"); + account2.set("age",18); + account2.set("sex",1); + accounts.add(account2); + + Row account3 = new Row(); + account3.set("username","michael3"); + account3.set("age",18); + account3.set("sex",1); + accounts.add(account3); + + + IDialect dialect = new OracleDialect(); + String sql = dialect.forInsertBatchWithFirstRowColumns(null,"tb_account",accounts); + System.out.println(sql); + } + +} From 4b1ddae7bd8cc59cd4a3223d47599d10fdc2ee35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 11:14:23 +0800 Subject: [PATCH 09/13] =?UTF-8?q?fixed:=20=E4=BF=AE=E5=A4=8D=20QueryWrappe?= =?UTF-8?q?r=20=E4=B8=8D=E8=83=BD=E4=BD=BF=E7=94=A8=E8=B6=85=E8=BF=87?= =?UTF-8?q?=E4=B8=80=E6=AC=A1;=20github=20close=20#49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mybatisflex/core/BaseMapper.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index 1faadd63..f09f9e88 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -542,17 +542,22 @@ public interface BaseMapper { */ default long selectCountByQuery(QueryWrapper queryWrapper) { List selectColumns = CPI.getSelectColumns(queryWrapper); - if (CollectionUtil.isEmpty(selectColumns)) { - queryWrapper.select(count()); - } - List objects = selectObjectListByQuery(queryWrapper); - Object object = objects == null || objects.isEmpty() ? null : objects.get(0); - if (object == null) { - return 0; - } else if (object instanceof Number) { - return ((Number) object).longValue(); - } else { - throw FlexExceptions.wrap("selectCountByQuery error, Can not get number value for queryWrapper: %s", queryWrapper); + try { + if (CollectionUtil.isEmpty(selectColumns)) { + queryWrapper.select(count()); + } + List objects = selectObjectListByQuery(queryWrapper); + Object object = objects == null || objects.isEmpty() ? null : objects.get(0); + if (object == null) { + return 0; + } else if (object instanceof Number) { + return ((Number) object).longValue(); + } else { + throw FlexExceptions.wrap("selectCountByQuery error, Can not get number value for queryWrapper: %s", queryWrapper); + } + } finally { + //fixed https://github.com/mybatis-flex/mybatis-flex/issues/49 + CPI.setSelectColumns(queryWrapper, selectColumns); } } From dc39e6083beb340d8c39898ee8e03a1637235c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 11:41:00 +0800 Subject: [PATCH 10/13] feat: add apt config "processor.tablesDefSuffix" close #I76Y46 #I78GMC #43 --- docs/zh/others/apt.md | 1 + .../processor/QueryEntityProcessor.java | 14 ++++++++++---- .../src/main/resources/mybatis-flex.properties | 2 ++ .../java/com/mybatisflex/test/AccountTest.java | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/zh/others/apt.md b/docs/zh/others/apt.md index 7b03fa46..f2357d57 100644 --- a/docs/zh/others/apt.md +++ b/docs/zh/others/apt.md @@ -24,6 +24,7 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编 | processor.baseMapperClass | 自定义 Mapper 的父类 | 全路径类名 | com.mybatisflex.core.BaseMapper | | processor.mappersPackage | 自定义 Mapper 生成的包名 | 合法的包名 | ${entityPackage}.mapper | | processor.tablesNameStyle | 生成辅助类的字段风格 | upperCase, lowerCase
upperCamelCase, lowerCamelCase | upperCase | +| processor.tablesDefSuffix | 生成的表对应的变量后缀 | string | 空字符串 | | processor.entity.ignoreSuffixes | 过滤 Entity 后缀 | string | - | diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/QueryEntityProcessor.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/QueryEntityProcessor.java index 1f667646..7a803795 100644 --- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/QueryEntityProcessor.java +++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/QueryEntityProcessor.java @@ -156,6 +156,9 @@ public class QueryEntityProcessor extends AbstractProcessor { //upperCase, lowerCase, upperCamelCase, lowerCamelCase String tablesNameStyle = props.getProperties().getProperty("processor.tablesNameStyle", "upperCase"); + //包名对应的变量后缀 + String tablesDefSuffix = props.getProperties().getProperty("processor.tablesDefSuffix", ""); + String[] entityIgnoreSuffixes = props.getProperties().getProperty("processor.entity.ignoreSuffixes", "").split(","); @@ -207,13 +210,15 @@ public class QueryEntityProcessor extends AbstractProcessor { } if (allInTables) { - String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, null, allInTables); + String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle + , tablesDefSuffix, null, allInTables); tablesContent.append(content); } //每一个 entity 生成一个独立的文件 else { String realGenPackage = genTablesPackage == null || genTablesPackage.trim().length() == 0 ? guessPackage.toString() : genTablesPackage; - String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, realGenPackage, allInTables); + String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle + , tablesDefSuffix, realGenPackage, allInTables); genClass(genPath, realGenPackage, entitySimpleName + "TableDef", content); } @@ -332,13 +337,14 @@ public class QueryEntityProcessor extends AbstractProcessor { private String buildTablesClass(String entityClass, String schema, String tableName, Map propertyAndColumns - , List defaultColumns, String tablesNameStyle, String realGenPackage, boolean allInTables) { + , List defaultColumns, String tablesNameStyle, String tablesDefSuffix, String realGenPackage, boolean allInTables) { // tableDefTemplate = " public static final @entityClassTableDef @tableField = new @entityClassTableDef(\"@tableName\");\n"; String tableDef = tableDefTemplate.replace("@entityClass", entityClass) .replace("@schema", schema) - .replace("@tableField", buildName(entityClass, tablesNameStyle)) + .replace("@tableField", buildName(entityClass, tablesNameStyle) + + (tablesDefSuffix != null ? tablesDefSuffix.trim() : "")) .replace("@tableName", tableName); diff --git a/mybatis-flex-test/mybatis-flex-spring-test/src/main/resources/mybatis-flex.properties b/mybatis-flex-test/mybatis-flex-spring-test/src/main/resources/mybatis-flex.properties index ec75864c..9215692f 100644 --- a/mybatis-flex-test/mybatis-flex-spring-test/src/main/resources/mybatis-flex.properties +++ b/mybatis-flex-test/mybatis-flex-spring-test/src/main/resources/mybatis-flex.properties @@ -1 +1,3 @@ processor.mappersGenerateEnable = true +processor.tablesNameStyle = lowerCase +processor.tablesDefSuffix = Def diff --git a/mybatis-flex-test/mybatis-flex-spring-test/src/test/java/com/mybatisflex/test/AccountTest.java b/mybatis-flex-test/mybatis-flex-spring-test/src/test/java/com/mybatisflex/test/AccountTest.java index efb482f8..ca256fe7 100644 --- a/mybatis-flex-test/mybatis-flex-spring-test/src/test/java/com/mybatisflex/test/AccountTest.java +++ b/mybatis-flex-test/mybatis-flex-spring-test/src/test/java/com/mybatisflex/test/AccountTest.java @@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.List; -import static com.mybatisflex.test.model.table.AccountTableDef.ACCOUNT; +import static com.mybatisflex.test.model.table.AccountTableDef.accountDef; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = AppConfig.class) @@ -33,7 +33,7 @@ public class AccountTest implements WithAssertions { @Test public void testSelectByQuery() { QueryWrapper queryWrapper = QueryWrapper.create() - .where(ACCOUNT.AGE.eq(18)); + .where(accountDef.age.eq(18)); List accounts = accountMapper.selectListByQuery(queryWrapper); assertThat(accounts.size()).isEqualTo(1); assertThat(accounts.get(0).getAge()).isEqualTo(18); From 7eaab96e351777ba4a2489f37b02888ba9a0ef6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 13:06:14 +0800 Subject: [PATCH 11/13] feat: add BaseMapper.selectCursorByQuery() --- .../java/com/mybatisflex/core/BaseMapper.java | 12 +++ .../core/mybatis/FlexConfiguration.java | 12 +++ .../core/mybatis/FlexResultSetHandler.java | 90 +++++++++++++++++++ .../mybatis/FlexSqlSessionFactoryBuilder.java | 4 +- .../core/transaction/TransactionContext.java | 26 +++++- .../transaction/TransactionalManager.java | 4 +- .../spring/FlexTransactionManager.java | 2 +- .../mybatisflex/test/EntityTestStarter.java | 31 ++++++- 8 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexResultSetHandler.java diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index f09f9e88..f8ac85b7 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -27,6 +27,7 @@ import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.util.*; import org.apache.ibatis.annotations.*; import org.apache.ibatis.builder.annotation.ProviderContext; +import org.apache.ibatis.cursor.Cursor; import java.io.Serializable; import java.util.*; @@ -442,6 +443,17 @@ public interface BaseMapper { return list; } + /** + * 根据 query 来构建条件查询游标数据 Cursor + * 该方法必须在事务中才能正常使用,非事务下无法获取数据 + * + * @param queryWrapper 查询条件 + * @return 游标数据 Cursor + */ + @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery") + Cursor selectCursorByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper); + + /** * 根据 query 来构建条件查询数据列表,要求返回的数据为 asType diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java index 5c700fa0..ce58b321 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java @@ -34,6 +34,7 @@ import org.apache.ibatis.executor.keygen.KeyGenerator; import org.apache.ibatis.executor.keygen.NoKeyGenerator; import org.apache.ibatis.executor.keygen.SelectKeyGenerator; import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.session.*; @@ -93,6 +94,17 @@ public class FlexConfiguration extends Configuration { } } + + @Override + public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement + , RowBounds rowBounds, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) { +// ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, +// resultHandler, boundSql, rowBounds); + ResultSetHandler resultSetHandler = new FlexResultSetHandler(executor, mappedStatement, parameterHandler, + resultHandler, boundSql, rowBounds); + return (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler); + } + /** * 替换为 FlexStatementHandler,主要用来为实体类的多主键做支持、和数据审计 * FlexStatementHandler 和 原生的 RoutingStatementHandler 对比,没有任何性能影响 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexResultSetHandler.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexResultSetHandler.java new file mode 100644 index 00000000..44c1b49f --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexResultSetHandler.java @@ -0,0 +1,90 @@ +/* + * 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.core.mybatis; + +import com.mybatisflex.core.transaction.TransactionContext; +import org.apache.ibatis.cursor.Cursor; +import org.apache.ibatis.cursor.defaults.DefaultCursor; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.executor.resultset.DefaultResultSetHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; + +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Iterator; + +public class FlexResultSetHandler extends DefaultResultSetHandler { + + public FlexResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql, RowBounds rowBounds) { + super(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); + } + + @Override + public Cursor handleCursorResultSets(Statement stmt) throws SQLException { + return new FlexCursor<>(super.handleCursorResultSets(stmt)); + } + + static class FlexCursor extends DefaultCursor { + + private Cursor originalCursor; + + public FlexCursor(Cursor cursor) { + super(null, null, null, null); + this.originalCursor = cursor; + TransactionContext.holdCursor(cursor); + } + + @Override + public void close() { + //非事务场景下,通过 releaseCursor 对 cursor 进行 close + if (TransactionContext.getXID() == null) { + TransactionContext.releaseCursor(); + } + //else 在事务的场景下,由事务主动关闭 + } + + @Override + public boolean isOpen() { + return originalCursor.isOpen(); + } + + @Override + public boolean isConsumed() { + return originalCursor.isConsumed(); + } + + @Override + public int getCurrentIndex() { + return originalCursor.getCurrentIndex(); + } + + @Override + public Iterator iterator() { + try { + return originalCursor.iterator(); + } catch (IllegalStateException e) { + if (TransactionContext.getXID() == null) { + throw new IllegalStateException(e.getMessage() + " Cursor must use in transaction."); + } + throw e; + } + } + } +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexSqlSessionFactoryBuilder.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexSqlSessionFactoryBuilder.java index 2502e236..9a0f43d8 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexSqlSessionFactoryBuilder.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexSqlSessionFactoryBuilder.java @@ -37,7 +37,7 @@ public class FlexSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder { @Override public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { - // 需要 mybaits v3.5.13+ + // 需要 mybatis v3.5.13+ // https://github.com/mybatis/mybatis-3/commit/d7826d71a7005a8b4d4e0e7a020db0f6c7e253a4 XMLConfigBuilder parser = new XMLConfigBuilder(FlexConfiguration.class, reader, environment, properties); return build(parser.parse()); @@ -59,7 +59,7 @@ public class FlexSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder { @Override public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { - // 需要 mybaits v3.5.13+ + // 需要 mybatis v3.5.13+ // https://github.com/mybatis/mybatis-3/commit/d7826d71a7005a8b4d4e0e7a020db0f6c7e253a4 XMLConfigBuilder parser = new XMLConfigBuilder(FlexConfiguration.class, inputStream, environment, properties); return build(parser.parse()); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionContext.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionContext.java index 599da7a6..4c0920b1 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionContext.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionContext.java @@ -16,11 +16,16 @@ package com.mybatisflex.core.transaction; +import org.apache.ibatis.cursor.Cursor; + +import java.io.IOException; + public class TransactionContext { private TransactionContext() {} private static final ThreadLocal XID_HOLDER = new ThreadLocal<>(); + private static final ThreadLocal> CURSOR_HOLDER = new ThreadLocal<>(); public static String getXID() { return XID_HOLDER.get(); @@ -28,10 +33,29 @@ public class TransactionContext { public static void release() { XID_HOLDER.remove(); + releaseCursor(); } - public static void hold(String xid) { + public static void releaseCursor() { + try { + Cursor cursor = CURSOR_HOLDER.get(); + if (cursor != null){ + try { + cursor.close(); + } catch (IOException e) { + } + } + }finally { + CURSOR_HOLDER.remove(); + } + } + + public static void holdXID(String xid) { XID_HOLDER.set(xid); } + public static void holdCursor(Cursor cursor) { + CURSOR_HOLDER.set(cursor); + } + } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionalManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionalManager.java index 85b91198..f5cb0389 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionalManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/transaction/TransactionalManager.java @@ -113,7 +113,7 @@ public class TransactionalManager { } finally { //恢复上一级事务 if (currentXID != null) { - TransactionContext.hold(currentXID); + TransactionContext.holdXID(currentXID); } } } @@ -147,7 +147,7 @@ public class TransactionalManager { public static String startTransactional() { String xid = UUID.randomUUID().toString(); - TransactionContext.hold(xid); + TransactionContext.holdXID(xid); return xid; } diff --git a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexTransactionManager.java b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexTransactionManager.java index aa5e02d2..96e1b7fa 100644 --- a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexTransactionManager.java +++ b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexTransactionManager.java @@ -46,7 +46,7 @@ public class FlexTransactionManager extends AbstractPlatformTransactionManager { @Override protected void doResume(Object transaction, Object suspendedResources) throws TransactionException { String xid = (String) suspendedResources; - TransactionContext.hold(xid); + TransactionContext.holdXID(xid); } @Override diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java index aae6fe96..350b0b58 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java @@ -19,13 +19,16 @@ import com.mybatisflex.core.MybatisFlexBootstrap; import com.mybatisflex.core.audit.AuditManager; import com.mybatisflex.core.audit.ConsoleMessageCollector; import com.mybatisflex.core.audit.MessageCollector; -import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.Db; +import org.apache.ibatis.cursor.Cursor; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import javax.sql.DataSource; +import java.util.function.Supplier; + import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT; import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE; @@ -138,8 +141,30 @@ public class EntityTestStarter { // // List articleDTOS = accountMapper.selectListByQueryAs(asWrapper, ArticleDTO.class); // System.out.println(articleDTOS); - Page paginate = accountMapper.paginateAs(Page.of(1, 10), asWrapper, ArticleDTO01.class); - System.out.println(paginate); +// Page paginate = accountMapper.paginateAs(Page.of(1, 10), asWrapper, ArticleDTO01.class); +// System.out.println(paginate); + + Db.tx(new Supplier() { + @Override + public Boolean get() { + Cursor accounts = accountMapper.selectCursorByQuery(asWrapper); + System.out.println(accounts.isOpen()); + for (Account account : accounts) { + System.out.println(accounts.isOpen()); + System.out.println(account); + } + System.out.println(accounts.isOpen()); + return true; + } + }); + +// Cursor accounts = accountMapper.selectCursorByQuery(asWrapper); +// System.out.println(accounts.isOpen()); +// for (Account account : accounts) { +// System.out.println(accounts.isOpen()); +// System.out.println(account); +// } +// System.out.println(accounts.isOpen()); // QueryWrapper queryWrapper = new QueryWrapper(); From f2439bd56d81d19f7fb558a1380fa7531cb8f486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 14:37:29 +0800 Subject: [PATCH 12/13] optimize: remove BaseMapper.__queryFields() method to MapperUtil --- .../java/com/mybatisflex/core/BaseMapper.java | 42 ++----------- .../com/mybatisflex/core/util/MapperUtil.java | 63 +++++++++++++++++++ 2 files changed, 67 insertions(+), 38 deletions(-) create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index 55332be7..e1cb9994 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -16,7 +16,6 @@ package com.mybatisflex.core; import com.mybatisflex.core.exception.FlexExceptions; -import com.mybatisflex.core.field.FieldQuery; import com.mybatisflex.core.field.FieldQueryBuilder; import com.mybatisflex.core.mybatis.MappedStatementTypes; import com.mybatisflex.core.paginate.Page; @@ -436,7 +435,7 @@ public interface BaseMapper { return Collections.emptyList(); } - __queryFields(list, consumers); + MapperUtil.queryFields(this, list, consumers); return list; } @@ -452,7 +451,6 @@ public interface BaseMapper { Cursor selectCursorByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper); - /** * 根据 query 来构建条件查询数据列表,要求返回的数据为 asType * 这种场景一般用在 left join 时,有多出了 entity 本身的字段内容,可以转换为 dto、vo 等场景时 @@ -481,7 +479,7 @@ public interface BaseMapper { if (list == null || list.isEmpty()) { return Collections.emptyList(); } else { - __queryFields(list, consumers); + MapperUtil.queryFields(this, list, consumers); return list; } } @@ -729,47 +727,15 @@ public interface BaseMapper { if (asType != null) { List records = selectListByQueryAs(queryWrapper, asType); - __queryFields(records, consumers); + MapperUtil.queryFields(this, records, consumers); page.setRecords(records); } else { List records = (List) selectListByQuery(queryWrapper); - __queryFields(records, consumers); + MapperUtil.queryFields(this, records, consumers); page.setRecords(records); } return page; } - default void __queryFields(List list, Consumer>[] consumers) { - if (CollectionUtil.isEmpty(list) || ArrayUtil.isEmpty(consumers) || consumers[0] == null) { - return; - } - list.forEach(entity -> { - for (Consumer> consumer : consumers) { - FieldQueryBuilder fieldQueryBuilder = new FieldQueryBuilder<>(entity); - consumer.accept(fieldQueryBuilder); - FieldQuery fieldQuery = fieldQueryBuilder.build(); - QueryWrapper childQuery = fieldQuery.getQueryWrapper(); - - FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField()); - - Class fieldType = fieldWrapper.getFieldType(); - Class mappingType = fieldWrapper.getMappingType(); - - Object value; - if (fieldType.isAssignableFrom(List.class)) { - value = selectListByQueryAs(childQuery, mappingType); - } else if (fieldType.isAssignableFrom(Set.class)) { - value = selectListByQueryAs(childQuery, mappingType); - value = new HashSet<>((Collection) value); - } else if (fieldType.isArray()) { - value = selectListByQueryAs(childQuery, mappingType); - value = ((List) value).toArray(); - } else { - value = selectOneByQueryAs(childQuery, mappingType); - } - fieldWrapper.set(value, entity); - } - }); - } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java new file mode 100644 index 00000000..451b00e4 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java @@ -0,0 +1,63 @@ +/* + * 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.core.util; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.core.field.FieldQuery; +import com.mybatisflex.core.field.FieldQueryBuilder; +import com.mybatisflex.core.query.QueryWrapper; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +public class MapperUtil { + + public static void queryFields(BaseMapper mapper, List list, Consumer>[] consumers) { + if (CollectionUtil.isEmpty(list) || ArrayUtil.isEmpty(consumers) || consumers[0] == null) { + return; + } + list.forEach(entity -> { + for (Consumer> consumer : consumers) { + FieldQueryBuilder fieldQueryBuilder = new FieldQueryBuilder<>(entity); + consumer.accept(fieldQueryBuilder); + FieldQuery fieldQuery = fieldQueryBuilder.build(); + QueryWrapper childQuery = fieldQuery.getQueryWrapper(); + + FieldWrapper fieldWrapper = FieldWrapper.of(entity.getClass(), fieldQuery.getField()); + + Class fieldType = fieldWrapper.getFieldType(); + Class mappingType = fieldWrapper.getMappingType(); + + Object value; + if (fieldType.isAssignableFrom(List.class)) { + value = mapper.selectListByQueryAs(childQuery, mappingType); + } else if (fieldType.isAssignableFrom(Set.class)) { + value = mapper.selectListByQueryAs(childQuery, mappingType); + value = new HashSet<>((Collection) value); + } else if (fieldType.isArray()) { + value = mapper.selectListByQueryAs(childQuery, mappingType); + value = ((List) value).toArray(); + } else { + value = mapper.selectOneByQueryAs(childQuery, mappingType); + } + fieldWrapper.set(value, entity); + } + }); + } +} From 24e68a715b85a9dadc67efce63c53d4d8715e066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Thu, 8 Jun 2023 14:52:22 +0800 Subject: [PATCH 13/13] optimize: move SqlUtil.getSelectOneResult method to MapperUtil --- .../java/com/mybatisflex/core/BaseMapper.java | 6 ++--- .../com/mybatisflex/core/util/MapperUtil.java | 19 ++++++++++++++ .../com/mybatisflex/core/util/SqlUtil.java | 25 ++++++------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index e1cb9994..0860ee05 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -345,7 +345,7 @@ public interface BaseMapper { * @return entity 数据 */ default T selectOneByQuery(QueryWrapper queryWrapper) { - return SqlUtil.getSelectOneResult(selectListByQuery(queryWrapper)); + return MapperUtil.getSelectOneResult(selectListByQuery(queryWrapper)); } @@ -357,7 +357,7 @@ public interface BaseMapper { * @return 数据内容 */ default R selectOneByQueryAs(QueryWrapper queryWrapper, Class asType) { - return SqlUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)); + return MapperUtil.getSelectOneResult(selectListByQueryAs(queryWrapper, asType)); } /** @@ -503,7 +503,7 @@ public interface BaseMapper { * @return 数据量 */ default Object selectObjectByQuery(QueryWrapper queryWrapper) { - return SqlUtil.getSelectOneResult(selectObjectListByQuery(queryWrapper)); + return MapperUtil.getSelectOneResult(selectObjectListByQuery(queryWrapper)); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java index 451b00e4..d08ab41d 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/MapperUtil.java @@ -19,6 +19,8 @@ import com.mybatisflex.core.BaseMapper; import com.mybatisflex.core.field.FieldQuery; import com.mybatisflex.core.field.FieldQueryBuilder; import com.mybatisflex.core.query.QueryWrapper; +import org.apache.ibatis.exceptions.TooManyResultsException; +import org.apache.ibatis.session.defaults.DefaultSqlSession; import java.util.Collection; import java.util.HashSet; @@ -60,4 +62,21 @@ public class MapperUtil { } }); } + + + + /** + * 搬运加改造 {@link DefaultSqlSession#selectOne(String, Object)} + */ + public static T getSelectOneResult(List list) { + if (list == null || list.isEmpty()) { + return null; + } + int size = list.size(); + if (size == 1) { + return list.get(0); + } + throw new TooManyResultsException( + "Expected one result (or null) to be returned by selectOne(), but found: " + size); + } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/SqlUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/SqlUtil.java index 584263ba..fedae9d1 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/SqlUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/SqlUtil.java @@ -15,12 +15,8 @@ */ package com.mybatisflex.core.util; -import org.apache.ibatis.exceptions.TooManyResultsException; -import org.apache.ibatis.session.defaults.DefaultSqlSession; - import java.time.LocalDateTime; import java.util.Date; -import java.util.List; import java.util.regex.Matcher; public class SqlUtil { @@ -83,6 +79,12 @@ public class SqlUtil { } + /** + * 替换 sql 中的问号 ? + * @param sql sql 内容 + * @param params 参数 + * @return 完整的 sql + */ public static String replaceSqlParams(String sql, Object[] params) { if (params != null && params.length > 0) { for (Object value : params) { @@ -113,19 +115,6 @@ public class SqlUtil { return sql; } - /** - * 搬运加改造 {@link DefaultSqlSession#selectOne(String, Object)} - */ - public static T getSelectOneResult(List list) { - if (list == null || list.isEmpty()) { - return null; - } - int size = list.size(); - if (size == 1) { - return list.get(0); - } - throw new TooManyResultsException( - "Expected one result (or null) to be returned by selectOne(), but found: " + size); - } + }