From 832c161cfb0eae973a84dc79d3beca4a5ca3371d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 13:09:22 +0800 Subject: [PATCH 01/10] feat: add schema support; close #I6VD6U --- .../java/com/mybatisflex/core/query/Join.java | 6 +- .../mybatisflex/core/query/QueryColumn.java | 2 +- .../mybatisflex/core/query/QueryTable.java | 31 ++++++- .../mybatisflex/core/query/QueryWrapper.java | 73 ++++++++++++---- .../com/mybatisflex/core/table/TableDef.java | 10 +++ .../com/mybatisflex/coretest/Account01.java | 84 +++++++++++++++++++ .../coretest/AccountSqlTester.java | 12 +++ .../processor/QueryEntityProcessor.java | 21 +++-- 8 files changed, 206 insertions(+), 33 deletions(-) create mode 100644 mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/Join.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/Join.java index 8f7c30de..848fe0d5 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/Join.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/Join.java @@ -43,9 +43,9 @@ public class Join implements Serializable { protected QueryCondition on; protected boolean effective; - public Join(String type, String table, boolean when) { + public Join(String type, QueryTable table, boolean when) { this.type = type; - this.queryTable = new QueryTable(table); + this.queryTable = table; this.effective = when; } @@ -65,7 +65,7 @@ public class Join implements Serializable { this.on = condition; } - QueryCondition getOnCondition(){ + QueryCondition getOnCondition() { return on; } 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 9bf82fa0..eac99e3c 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 @@ -53,7 +53,7 @@ public class QueryColumn implements Serializable { public QueryColumn(TableDef tableDef, String name) { SqlUtil.keepColumnSafely(name); - this.table = new QueryTable(tableDef.getTableName()); + this.table = new QueryTable(tableDef); this.name = name; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java index 2268fcb1..e0d37121 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java @@ -16,6 +16,8 @@ package com.mybatisflex.core.query; import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.table.TableDef; +import com.mybatisflex.core.util.StringUtil; import java.io.Serializable; import java.util.Objects; @@ -25,12 +27,18 @@ import java.util.Objects; */ public class QueryTable implements Serializable { + protected String schema; protected String name; protected String alias; public QueryTable() { } + public QueryTable(TableDef tableDef) { + this.name = tableDef.getTableName(); + this.schema = tableDef.getSchema(); + } + public QueryTable(String name) { this.name = name; } @@ -55,21 +63,38 @@ public class QueryTable implements Serializable { } boolean isSameTable(QueryTable table) { - return table != null && Objects.equals(name, table.name); + if (table == null) { + return false; + } + if (StringUtil.isNotBlank(alias) && StringUtil.isNotBlank(table.alias)) { + if (Objects.equals(alias, table.alias)) { + return false; + } + } + return Objects.equals(name, table.name); } + Object[] getValueArray() { return WrapperUtil.NULL_PARA_ARRAY; } public String toSql(IDialect dialect) { - return dialect.wrap(name) + WrapperUtil.buildAsAlias(alias, dialect); + String sql; + if (StringUtil.isNotBlank(schema)) { + sql = dialect.wrap(schema) + "." + dialect.wrap(name) + WrapperUtil.buildAsAlias(alias, dialect); + } else { + sql = dialect.wrap(name) + WrapperUtil.buildAsAlias(alias, dialect); + } + return sql; } + @Override public String toString() { return "QueryTable{" + - "name='" + name + '\'' + + "schema='" + schema + '\'' + + ", name='" + name + '\'' + ", alias='" + alias + '\'' + '}'; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java index 4db61cd0..4905172a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java @@ -42,7 +42,7 @@ public class QueryWrapper extends BaseQueryWrapper { public QueryWrapper from(TableDef... tableDefs) { for (TableDef tableDef : tableDefs) { - from(new QueryTable(tableDef.getTableName())); + from(new QueryTable(tableDef)); } return this; } @@ -151,21 +151,20 @@ public class QueryWrapper extends BaseQueryWrapper { public Joiner leftJoin(String table) { - return joining(Join.TYPE_LEFT, table, true); + return joining(Join.TYPE_LEFT, new QueryTable(table), true); } public Joiner leftJoinIf(String table, boolean when) { - return joining(Join.TYPE_LEFT, table, when); + return joining(Join.TYPE_LEFT, new QueryTable(table), when); } public Joiner leftJoin(TableDef table) { - return joining(Join.TYPE_LEFT, table.getTableName(), true); + return joining(Join.TYPE_LEFT, new QueryTable(table), true); } - public Joiner leftJoinIf(TableDef table, boolean when) { - return joining(Join.TYPE_LEFT, table.getTableName(), when); + return joining(Join.TYPE_LEFT, new QueryTable(table), when); } public Joiner leftJoin(QueryWrapper table) { @@ -176,12 +175,21 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_LEFT, table, when); } + public Joiner rightJoin(String table) { - return joining(Join.TYPE_RIGHT, table, true); + return joining(Join.TYPE_RIGHT, new QueryTable(table), true); } public Joiner rightJoinIf(String table, boolean when) { - return joining(Join.TYPE_RIGHT, table, when); + return joining(Join.TYPE_RIGHT, new QueryTable(table), when); + } + + public Joiner rightJoinIf(TableDef table) { + return joining(Join.TYPE_RIGHT, new QueryTable(table), true); + } + + public Joiner rightJoinIf(TableDef table, boolean when) { + return joining(Join.TYPE_RIGHT, new QueryTable(table), when); } public Joiner rightJoin(QueryWrapper table) { @@ -192,12 +200,13 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_RIGHT, table, when); } + public Joiner innerJoin(String table) { - return joining(Join.TYPE_INNER, table, true); + return joining(Join.TYPE_INNER, new QueryTable(table), true); } public Joiner innerJoinIf(String table, boolean when) { - return joining(Join.TYPE_INNER, table, when); + return joining(Join.TYPE_INNER, new QueryTable(table), when); } public Joiner innerJoin(TableDef table) { @@ -205,7 +214,7 @@ public class QueryWrapper extends BaseQueryWrapper { } public Joiner innerJoinIf(TableDef table, boolean when) { - return joining(Join.TYPE_INNER, table.getTableName(), when); + return joining(Join.TYPE_INNER, new QueryTable(table), when); } public Joiner innerJoin(QueryWrapper table) { @@ -216,12 +225,21 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_INNER, table, when); } + public Joiner fullJoin(String table) { - return joining(Join.TYPE_FULL, table, true); + return joining(Join.TYPE_FULL, new QueryTable(table), true); } public Joiner fullJoinIf(String table, boolean when) { - return joining(Join.TYPE_FULL, table, when); + return joining(Join.TYPE_FULL, new QueryTable(table), when); + } + + public Joiner fullJoinIf(TableDef table) { + return joining(Join.TYPE_FULL, new QueryTable(table), true); + } + + public Joiner fullJoinIf(TableDef table, boolean when) { + return joining(Join.TYPE_FULL, new QueryTable(table), when); } public Joiner fullJoin(QueryWrapper table) { @@ -232,12 +250,21 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_FULL, table, when); } + public Joiner crossJoin(String table) { - return joining(Join.TYPE_CROSS, table, true); + return joining(Join.TYPE_CROSS, new QueryTable(table), true); } public Joiner crossJoinIf(String table, boolean when) { - return joining(Join.TYPE_CROSS, table, when); + return joining(Join.TYPE_CROSS, new QueryTable(table), when); + } + + public Joiner crossJoinIf(TableDef table) { + return joining(Join.TYPE_CROSS, new QueryTable(table), true); + } + + public Joiner crossJoinIf(TableDef table, boolean when) { + return joining(Join.TYPE_CROSS, new QueryTable(table), when); } public Joiner crossJoin(QueryWrapper table) { @@ -248,12 +275,21 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_CROSS, table, when); } + public Joiner join(String table) { - return joining(Join.TYPE_JOIN, table, true); + return joining(Join.TYPE_JOIN, new QueryTable(table), true); } public Joiner join(String table, boolean when) { - return joining(Join.TYPE_JOIN, table, when); + return joining(Join.TYPE_JOIN, new QueryTable(table), when); + } + + public Joiner join(TableDef table) { + return joining(Join.TYPE_JOIN, new QueryTable(table), true); + } + + public Joiner join(TableDef table, boolean when) { + return joining(Join.TYPE_JOIN, new QueryTable(table), when); } public Joiner join(QueryWrapper table) { @@ -264,6 +300,7 @@ public class QueryWrapper extends BaseQueryWrapper { return joining(Join.TYPE_JOIN, table, when); } + public QueryWrapper union(QueryWrapper unionQuery) { if (unions == null) { unions = new ArrayList<>(); @@ -297,7 +334,7 @@ public class QueryWrapper extends BaseQueryWrapper { // } - protected Joiner joining(String type, String table, boolean condition) { + protected Joiner joining(String type, QueryTable table, boolean condition) { Join join = new Join(type, table, condition); addJoinTable(join.getQueryTable()); return new Joiner<>(addJoin(join), join); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java index 1abe0b8e..e70f79d2 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java @@ -21,8 +21,14 @@ import java.io.Serializable; public class TableDef implements Serializable { + private String schema; private final String tableName; + public TableDef(String schema, String tableName) { + this.schema = schema; + this.tableName = tableName; + } + public TableDef(String tableName) { this.tableName = tableName; } @@ -31,6 +37,10 @@ public class TableDef implements Serializable { return tableName; } + public String getSchema() { + return schema; + } + public QueryTable as(String alias) { return new QueryTable(tableName, alias); } diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java new file mode 100644 index 00000000..7242448f --- /dev/null +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java @@ -0,0 +1,84 @@ +package com.mybatisflex.coretest; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.util.Date; + +@Table(value = "tb_account",schema = "flex") +public class Account01 { + + @Id + private Long id; + + private String userName; + + private Date birthday; + + private int sex; + + private Integer age; + + private boolean isNormal; + + @Column(isLogicDelete = true) + private Boolean isDelete; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public int getSex() { + return sex; + } + + public void setSex(int sex) { + this.sex = sex; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public boolean isNormal() { + return isNormal; + } + + public void setNormal(boolean normal) { + isNormal = normal; + } + + public Boolean getDelete() { + return isDelete; + } + + public void setDelete(Boolean delete) { + isDelete = delete; + } +} diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java index 6e67d2eb..02ea99d2 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java @@ -13,6 +13,7 @@ import org.junit.Test; import java.util.Arrays; import static com.mybatisflex.core.query.QueryMethods.*; +import static com.mybatisflex.coretest.table.Account01TableDef.ACCOUNT01; import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT; import static com.mybatisflex.coretest.table.ArticleTableDef.ARTICLE; @@ -30,6 +31,17 @@ public class AccountSqlTester { System.out.println(sql); } + @Test + public void testSelectWithSchemaSql() { + QueryWrapper query = new QueryWrapper() + .select() + .from(ACCOUNT01); + + IDialect dialect = new CommonsDialectImpl(); + String sql = dialect.forSelectByQuery(query); + System.out.println(sql); + } + @Test public void testSelectColumnsSql() { QueryWrapper query = new QueryWrapper() 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 07e9381b..1f667646 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 @@ -81,7 +81,7 @@ public class QueryEntityProcessor extends AbstractProcessor { "@classesInfo" + "}\n"; - private static final String tableDefTemplate = "\n\n public static final @entityClassTableDef @tableField = new @entityClassTableDef(\"@tableName\");\n"; + private static final String tableDefTemplate = "\n\n public static final @entityClassTableDef @tableField = new @entityClassTableDef(\"@schema\", \"@tableName\");\n"; private static final String singleEntityClassTemplate = "package @package;\n" + "\n" + @@ -96,8 +96,8 @@ public class QueryEntityProcessor extends AbstractProcessor { "@defaultColumns" + "@allColumns" + "\n" + - " public @entityClassTableDef(String tableName) {\n" + - " super(tableName);\n" + + " public @entityClassTableDef(String schema, String tableName) {\n" + + " super(schema, tableName);\n" + " }\n" + "}\n"; @@ -109,8 +109,8 @@ public class QueryEntityProcessor extends AbstractProcessor { "@defaultColumns" + "@allColumns" + "\n" + - " public @entityClassTableDef(String tableName) {\n" + - " super(tableName);\n" + + " public @entityClassTableDef(String schema, String tableName) {\n" + + " super(schema, tableName);\n" + " }\n" + " }\n"; @@ -177,6 +177,10 @@ public class QueryEntityProcessor extends AbstractProcessor { } } + String schema = table != null && table.value().trim().length() != 0 + ? table.schema() + : ""; + String tableName = table != null && table.value().trim().length() != 0 ? table.value() : firstCharToLowerCase(entityClassElement.getSimpleName().toString()); @@ -203,13 +207,13 @@ public class QueryEntityProcessor extends AbstractProcessor { } if (allInTables) { - String content = buildTablesClass(entitySimpleName, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, null, allInTables); + String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, null, allInTables); tablesContent.append(content); } //每一个 entity 生成一个独立的文件 else { String realGenPackage = genTablesPackage == null || genTablesPackage.trim().length() == 0 ? guessPackage.toString() : genTablesPackage; - String content = buildTablesClass(entitySimpleName, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, realGenPackage, allInTables); + String content = buildTablesClass(entitySimpleName, schema, tableName, propertyAndColumns, defaultColumns, tablesNameStyle, realGenPackage, allInTables); genClass(genPath, realGenPackage, entitySimpleName + "TableDef", content); } @@ -327,12 +331,13 @@ public class QueryEntityProcessor extends AbstractProcessor { } - private String buildTablesClass(String entityClass, String tableName, Map propertyAndColumns + private String buildTablesClass(String entityClass, String schema, String tableName, Map propertyAndColumns , List defaultColumns, String tablesNameStyle, 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("@tableName", tableName); From d35155ea220ea690d500bb24334810b9d191d2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 13:43:19 +0800 Subject: [PATCH 02/10] feat: add QueryWrapper.toDebugSQL() method for debug --- .../mybatisflex/core/audit/AuditMessage.java | 37 ++----------------- .../mybatisflex/core/query/QueryWrapper.java | 8 ++++ .../com/mybatisflex/core/util/SqlUtil.java | 35 ++++++++++++++++++ 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/AuditMessage.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/AuditMessage.java index 6d69a496..4d8792b4 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/AuditMessage.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/AuditMessage.java @@ -17,20 +17,17 @@ package com.mybatisflex.core.audit; import com.mybatisflex.core.mybatis.TypeHandlerObject; import com.mybatisflex.core.util.ClassUtil; -import com.mybatisflex.core.util.DateUtil; +import com.mybatisflex.core.util.SqlUtil; import java.io.Serializable; import java.lang.reflect.Array; import java.lang.reflect.Proxy; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; public class AuditMessage implements Serializable { @@ -147,37 +144,11 @@ public class AuditMessage implements Serializable { } public String getFullSql() { - String sql = getQuery(); - List params = getQueryParams(); - if (params != null) { - for (Object value : params) { - // null - if (value == null) { - sql = sql.replaceFirst("\\?", "null"); - } - // number - else if (value instanceof Number || value instanceof Boolean) { - sql = sql.replaceFirst("\\?", value.toString()); - } - // other - else { - StringBuilder sb = new StringBuilder(); - sb.append("'"); - if (value instanceof Date) { - sb.append(DateUtil.toDateTimeString((Date) value)); - } else if (value instanceof LocalDateTime) { - sb.append(DateUtil.toDateTimeString(DateUtil.toDate((LocalDateTime) value))); - } else { - sb.append(value); - } - sb.append("'"); - sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(sb.toString())); - } - } - } - return sql; + List queryParams = getQueryParams(); + return SqlUtil.replaceSqlParams(getQuery(), queryParams == null ? null : queryParams.toArray()); } + private PreparedStatement createPreparedStatement() { return (PreparedStatement) Proxy.newProxyInstance( AuditMessage.class.getClassLoader(), diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java index 4905172a..f4014c21 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java @@ -15,10 +15,12 @@ */ package com.mybatisflex.core.query; +import com.mybatisflex.core.dialect.DialectFactory; import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.table.TableDef; import com.mybatisflex.core.util.ArrayUtil; import com.mybatisflex.core.util.CollectionUtil; +import com.mybatisflex.core.util.SqlUtil; import com.mybatisflex.core.util.StringUtil; import java.util.*; @@ -526,4 +528,10 @@ public class QueryWrapper extends BaseQueryWrapper { } + public String toDebugSQL() { + String sql = DialectFactory.getDialect().forSelectByQuery(this); + return SqlUtil.replaceSqlParams(sql, getValueArray()); + } + + } 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 cf7878b8..b36b2d93 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,6 +15,10 @@ */ package com.mybatisflex.core.util; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.regex.Matcher; + public class SqlUtil { @@ -72,4 +76,35 @@ public class SqlUtil { return result != null && result.longValue() > 0; } + + public static String replaceSqlParams(String sql, Object[] params){ + if (params != null && params.length > 0) { + for (Object value : params) { + // null + if (value == null) { + sql = sql.replaceFirst("\\?", "null"); + } + // number + else if (value instanceof Number || value instanceof Boolean) { + sql = sql.replaceFirst("\\?", value.toString()); + } + // other + else { + StringBuilder sb = new StringBuilder(); + sb.append("'"); + if (value instanceof Date) { + sb.append(DateUtil.toDateTimeString((Date) value)); + } else if (value instanceof LocalDateTime) { + sb.append(DateUtil.toDateTimeString(DateUtil.toDate((LocalDateTime) value))); + } else { + sb.append(value); + } + sb.append("'"); + sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(sb.toString())); + } + } + } + return sql; + } + } From 47f41d4e0584611493f6cfffc4c50ed4211f2f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 15:14:43 +0800 Subject: [PATCH 03/10] feat: add dynamic table support; close #I6VRMF #I6WS3E #I72X21 --- .../mybatisflex/core/dialect/IDialect.java | 10 +- .../core/dialect/impl/CommonsDialectImpl.java | 19 +-- .../mybatisflex/core/query/QueryColumn.java | 64 +++++++--- .../core/query/QueryCondition.java | 4 +- .../mybatisflex/core/query/QueryTable.java | 20 +++- .../mybatisflex/core/query/WrapperUtil.java | 33 ------ .../core/table/DynamicSchemaProcessor.java | 20 ++++ .../core/table/DynamicTableProcessor.java | 20 ++++ .../com/mybatisflex/core/table/TableDef.java | 2 +- .../com/mybatisflex/core/table/TableInfo.java | 10 +- .../mybatisflex/core/table/TableManager.java | 110 ++++++++++++++++++ .../com/mybatisflex/coretest/Account01.java | 2 +- .../coretest/AccountSqlTester.java | 33 +++++- .../mybatisflex/test/EntityTestStarter.java | 24 ++-- 14 files changed, 283 insertions(+), 88 deletions(-) create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicSchemaProcessor.java create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicTableProcessor.java create mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.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 5fefcc4e..d7cc2829 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 @@ -18,6 +18,7 @@ package com.mybatisflex.core.dialect; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.row.Row; import com.mybatisflex.core.table.TableInfo; +import com.mybatisflex.core.table.TableManager; import java.util.List; @@ -25,6 +26,14 @@ public interface IDialect { String wrap(String keyword); + default String getRealTable(String table) { + return TableManager.getRealTable(table); + } + + default String getRealSchema(String schema) { + return TableManager.getRealSchema(schema); + } + String forHint(String hintString); String forInsertRow(String tableName, Row row); @@ -54,7 +63,6 @@ public interface IDialect { String buildWhereConditionSql(QueryWrapper queryWrapper); - //////for entity ///// String forInsertEntity(TableInfo tableInfo, Object entity, boolean ignoreNulls); 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 d0cb577e..c461acf9 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 @@ -59,6 +59,7 @@ public class CommonsDialectImpl implements IDialect { return "*".equals(keyword) ? keyword : keywordWrap.wrap(keyword); } + @Override public String forHint(String hintString) { return StringUtil.isNotBlank(hintString) ? "/*+ " + hintString + " */ " : ""; @@ -81,7 +82,7 @@ public class CommonsDialectImpl implements IDialect { index++; } - String sql = "INSERT INTO " + wrap(tableName) + + String sql = "INSERT INTO " + wrap(getRealTable(tableName)) + "(" + fields + ") VALUES " + "(" + questions + ")"; return sql; @@ -111,7 +112,7 @@ public class CommonsDialectImpl implements IDialect { } } - String sql = "INSERT INTO " + wrap(tableName) + + String sql = "INSERT INTO " + wrap(getRealTable(tableName)) + "(" + fields + ") VALUES " + questions; return sql; } @@ -121,7 +122,7 @@ public class CommonsDialectImpl implements IDialect { public String forDeleteById(String tableName, String[] primaryKeys) { StringBuilder sql = new StringBuilder(); sql.append("DELETE FROM "); - sql.append(wrap(tableName)); + sql.append(wrap(getRealTable(tableName))); sql.append(" WHERE "); for (int i = 0; i < primaryKeys.length; i++) { if (i > 0) { @@ -137,7 +138,7 @@ public class CommonsDialectImpl implements IDialect { public String forDeleteBatchByIds(String tableName, String[] primaryKeys, Object[] ids) { StringBuilder sql = new StringBuilder(); sql.append("DELETE FROM "); - sql.append(wrap(tableName)); + sql.append(wrap(getRealTable(tableName))); sql.append(" WHERE "); //多主键的场景 @@ -180,7 +181,7 @@ public class CommonsDialectImpl implements IDialect { Set modifyAttrs = row.obtainModifyAttrs(); String[] primaryKeys = RowCPI.obtainsPrimaryKeyStrings(row); - sql.append("UPDATE ").append(wrap(tableName)).append(" SET "); + sql.append("UPDATE ").append(wrap(getRealTable(tableName))).append(" SET "); int index = 0; for (Map.Entry e : row.entrySet()) { String colName = e.getKey(); @@ -215,7 +216,7 @@ public class CommonsDialectImpl implements IDialect { } String tableName = queryTables.get(0).getName(); - sql.append("UPDATE ").append(wrap(tableName)).append(" SET "); + sql.append("UPDATE ").append(wrap(getRealTable(tableName))).append(" SET "); int index = 0; for (String modifyAttr : modifyAttrs) { if (index > 0) { @@ -249,7 +250,7 @@ public class CommonsDialectImpl implements IDialect { @Override public String forSelectOneById(String tableName, String[] primaryKeys, Object[] primaryValues) { StringBuilder sql = new StringBuilder("SELECT * FROM "); - sql.append(wrap(tableName)).append(" WHERE "); + sql.append(wrap(getRealTable(tableName))).append(" WHERE "); for (int i = 0; i < primaryKeys.length; i++) { if (i > 0) { sql.append(" AND "); @@ -875,7 +876,7 @@ public class CommonsDialectImpl implements IDialect { || normalValueOfLogicDelete instanceof Boolean) { return normalValueOfLogicDelete; } - return "'" + normalValueOfLogicDelete.toString() + "'"; + return "'" + normalValueOfLogicDelete + "'"; } @@ -885,7 +886,7 @@ public class CommonsDialectImpl implements IDialect { || deletedValueOfLogicDelete instanceof Boolean) { return deletedValueOfLogicDelete; } - return "'" + deletedValueOfLogicDelete.toString() + "'"; + return "'" + deletedValueOfLogicDelete + "'"; } } 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 eac99e3c..708157e4 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 @@ -18,10 +18,7 @@ package com.mybatisflex.core.query; import com.mybatisflex.core.dialect.IDialect; import com.mybatisflex.core.table.TableDef; -import com.mybatisflex.core.util.LambdaGetter; -import com.mybatisflex.core.util.LambdaUtil; -import com.mybatisflex.core.util.SqlUtil; -import com.mybatisflex.core.util.StringUtil; +import com.mybatisflex.core.util.*; import java.io.Serializable; import java.util.Collection; @@ -45,9 +42,9 @@ public class QueryColumn implements Serializable { this.name = name; } - public QueryColumn(String tableName, String name) { + public QueryColumn(String schema, String tableName, String name) { SqlUtil.keepColumnSafely(name); - this.table = new QueryTable(tableName); + this.table = new QueryTable(schema, tableName); this.name = name; } @@ -358,25 +355,56 @@ public class QueryColumn implements Serializable { } - protected String wrap(IDialect dialect, String table, String column) { - if (StringUtil.isNotBlank(table)) { - return dialect.wrap(table) + "." + dialect.wrap(column); - } else { - return dialect.wrap(column); - } - } - String toConditionSql(List queryTables, IDialect dialect) { - String tableName = WrapperUtil.getColumnTableName(queryTables, table); - return wrap(dialect, tableName, name); + QueryTable selectTable = getSelectTable(queryTables, table); + if (selectTable == null) { + return dialect.wrap(name); + } else { + if (StringUtil.isNotBlank(selectTable.alias)) { + return dialect.wrap(selectTable.alias) + "." + dialect.wrap(name); + } else if (StringUtil.isNotBlank(selectTable.getSchema()) && StringUtil.isNotBlank(selectTable.getName())) { + return dialect.wrap(dialect.getRealSchema(selectTable.schema)) + "." + dialect.wrap(dialect.getRealTable(selectTable.getName())) + "." + dialect.wrap(name); + } else if (StringUtil.isNotBlank(selectTable.getName())) { + return dialect.wrap(dialect.getRealTable(selectTable.getName())) + "." + dialect.wrap(name); + } else { + return dialect.wrap(name); + } + } } String toSelectSql(List queryTables, IDialect dialect) { - String tableName = WrapperUtil.getColumnTableName(queryTables, table); - return wrap(dialect, tableName, name) + WrapperUtil.buildAsAlias(alias, dialect); + return toConditionSql(queryTables, dialect) + WrapperUtil.buildAsAlias(alias, dialect); } + + QueryTable getSelectTable(List queryTables, QueryTable columnTable) { + if (queryTables == null || queryTables.isEmpty()) { + return null; + } + + if (queryTables.size() == 1 && queryTables.get(0).isSameTable(columnTable)) { + //ignore table + return null; + } + + if (CollectionUtil.isEmpty(queryTables)) { + return columnTable; + } + + if (columnTable == null && queryTables.size() == 1) { + return queryTables.get(0); + } + + for (QueryTable table : queryTables) { + if (table.isSameTable(columnTable)) { + return table; + } + } + return columnTable; + } + + @Override public String toString() { return "QueryColumn{" + diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java index b69bb0f2..654ae009 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java @@ -62,9 +62,9 @@ public class QueryCondition implements Serializable { } - public static QueryCondition create(String table, String column, String logic, Object value) { + public static QueryCondition create(String schema, String table, String column, String logic, Object value) { QueryCondition condition = new QueryCondition(); - condition.setColumn(new QueryColumn(table, column)); + condition.setColumn(new QueryColumn(schema, table, column)); condition.setLogic(logic); condition.setValue(value); return condition; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java index e0d37121..c59e2019 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryTable.java @@ -43,11 +43,25 @@ public class QueryTable implements Serializable { this.name = name; } - public QueryTable(String table, String alias) { + public QueryTable(String schema, String name) { + this.schema = schema; + this.name = name; + } + + public QueryTable(String schema, String table, String alias) { + this.schema = schema; this.name = table; this.alias = alias; } + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } + public String getName() { return name; } @@ -82,9 +96,9 @@ public class QueryTable implements Serializable { public String toSql(IDialect dialect) { String sql; if (StringUtil.isNotBlank(schema)) { - sql = dialect.wrap(schema) + "." + dialect.wrap(name) + WrapperUtil.buildAsAlias(alias, dialect); + sql = dialect.wrap(dialect.getRealSchema(schema)) + "." + dialect.wrap(dialect.getRealTable(name)) + WrapperUtil.buildAsAlias(alias, dialect); } else { - sql = dialect.wrap(name) + WrapperUtil.buildAsAlias(alias, dialect); + sql = dialect.wrap(dialect.getRealTable(name)) + WrapperUtil.buildAsAlias(alias, dialect); } return sql; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/WrapperUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/WrapperUtil.java index cd089694..47cc19ec 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/WrapperUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/WrapperUtil.java @@ -18,7 +18,6 @@ package com.mybatisflex.core.query; import com.mybatisflex.core.dialect.IDialect; import com.mybatisflex.core.util.ClassUtil; -import com.mybatisflex.core.util.CollectionUtil; import com.mybatisflex.core.util.EnumWrapper; import com.mybatisflex.core.util.StringUtil; @@ -132,39 +131,7 @@ class WrapperUtil { } - public static String getColumnTableName(List queryTables, QueryTable queryTable) { - if (queryTables == null) { - return ""; - } - if (queryTables.size() == 1 && queryTables.get(0).isSameTable(queryTable)) { - return ""; - } - - QueryTable realTable = getRealTable(queryTables, queryTable); - if (realTable == null) { - return ""; - } - - return StringUtil.isNotBlank(realTable.alias) ? realTable.alias : realTable.name; - } - - public static QueryTable getRealTable(List queryTables, QueryTable queryTable) { - if (CollectionUtil.isEmpty(queryTables)) { - return queryTable; - } - - if (queryTable == null && queryTables.size() == 1) { - return queryTables.get(0); - } - - for (QueryTable table : queryTables) { - if (table.isSameTable(queryTable)) { - return table; - } - } - return queryTable; - } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicSchemaProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicSchemaProcessor.java new file mode 100644 index 00000000..80dc13ce --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicSchemaProcessor.java @@ -0,0 +1,20 @@ +/** + * 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.table; + +public interface DynamicSchemaProcessor { + String process(String schema); +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicTableProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicTableProcessor.java new file mode 100644 index 00000000..e33b29e8 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/DynamicTableProcessor.java @@ -0,0 +1,20 @@ +/** + * 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.table; + +public interface DynamicTableProcessor { + String process(String tableName); +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java index e70f79d2..a8803d2e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableDef.java @@ -42,7 +42,7 @@ public class TableDef implements Serializable { } public QueryTable as(String alias) { - return new QueryTable(tableName, alias); + return new QueryTable(schema, tableName, alias); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index a90b46e3..83022002 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -577,12 +577,12 @@ public class TableInfo { if (versionValue == null) { throw FlexExceptions.wrap("The version value of entity[%s] must not be null.", entity); } - queryWrapper.and(QueryCondition.create(tableName, versionColumn, QueryCondition.LOGIC_EQUALS, versionValue)); + queryWrapper.and(QueryCondition.create(schema, tableName, versionColumn, QueryCondition.LOGIC_EQUALS, versionValue)); } //逻辑删除 if (StringUtil.isNotBlank(logicDeleteColumn)) { - queryWrapper.and(QueryCondition.create(tableName, logicDeleteColumn, QueryCondition.LOGIC_EQUALS + queryWrapper.and(QueryCondition.create(schema, tableName, logicDeleteColumn, QueryCondition.LOGIC_EQUALS , FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete())); } @@ -590,9 +590,9 @@ public class TableInfo { Object[] tenantIdArgs = buildTenantIdArgs(); if (ArrayUtil.isNotEmpty(tenantIdArgs)) { if (tenantIdArgs.length == 1) { - queryWrapper.and(QueryCondition.create(tableName, tenantIdColumn, QueryCondition.LOGIC_EQUALS, tenantIdArgs[0])); + queryWrapper.and(QueryCondition.create(schema, tableName, tenantIdColumn, QueryCondition.LOGIC_EQUALS, tenantIdArgs[0])); } else { - queryWrapper.and(QueryCondition.create(tableName, tenantIdColumn, QueryCondition.LOGIC_IN, tenantIdArgs)); + queryWrapper.and(QueryCondition.create(schema, tableName, tenantIdColumn, QueryCondition.LOGIC_IN, tenantIdArgs)); } } @@ -647,7 +647,7 @@ public class TableInfo { public List getDefaultQueryColumn() { return Arrays.stream(defaultColumns) - .map(name -> new QueryColumn(getTableName(), name)) + .map(name -> new QueryColumn(schema, getTableName(), name)) .collect(Collectors.toList()); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java new file mode 100644 index 00000000..ef97600c --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java @@ -0,0 +1,110 @@ +/** + * 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.table; + +import com.mybatisflex.core.util.StringUtil; + +import java.util.HashMap; +import java.util.Map; + +public class TableManager { + + private static DynamicSchemaProcessor dynamicSchemaProcessor; + private static DynamicTableProcessor dynamicTableProcessor; + + private static final ThreadLocal> tableNameMappingTL = ThreadLocal.withInitial(HashMap::new); + private static final ThreadLocal> schemaMappingTL = ThreadLocal.withInitial(HashMap::new); + + + public static DynamicSchemaProcessor getDynamicSchemaProcessor() { + return dynamicSchemaProcessor; + } + + public static void setDynamicSchemaProcessor(DynamicSchemaProcessor dynamicSchemaProcessor) { + TableManager.dynamicSchemaProcessor = dynamicSchemaProcessor; + } + + public static DynamicTableProcessor getDynamicTableProcessor() { + return dynamicTableProcessor; + } + + public static void setDynamicTableProcessor(DynamicTableProcessor dynamicTableProcessor) { + TableManager.dynamicTableProcessor = dynamicTableProcessor; + } + + + public static void setHintTableMapping(String tableName, String mappingTable) { + tableNameMappingTL.get().put(tableName, mappingTable); + } + + public static String getHintTableMapping(String tableName) { + return tableNameMappingTL.get().get(tableName); + } + + public static void setHintSchemaMapping(String schema, String mappingSchema) { + schemaMappingTL.get().put(schema, mappingSchema); + } + + public static String getHintSchemaMapping(String schema) { + return schemaMappingTL.get().get(schema); + } + + + public static String getRealTable(String tableName) { + if (dynamicTableProcessor == null) { + return tableName; + } + + Map mapping = tableNameMappingTL.get(); + + String dynamicTableName = mapping.get(tableName); + if (StringUtil.isNotBlank(dynamicTableName)) { + return dynamicTableName; + } + + dynamicTableName = dynamicTableProcessor.process(tableName); + mapping.put(tableName, dynamicTableName); + return dynamicTableName; + } + + + public static String getRealSchema(String schema) { + if (dynamicSchemaProcessor == null) { + return schema; + } + + Map mapping = schemaMappingTL.get(); + String dynamiSchema = mapping.get(schema); + if (StringUtil.isNotBlank(dynamiSchema)) { + return dynamiSchema; + } + + dynamiSchema = dynamicSchemaProcessor.process(schema); + mapping.put(schema, dynamiSchema); + return dynamiSchema; + } + + +// public static void clear() { +// if (dynamicTableProcessor != null) { +// tableNameMappingTL.remove(); +// } +// if (dynamicSchemaProcessor != null) { +// schemaMappingTL.remove(); +// } +// } + +} diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java index 7242448f..d33ffc95 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/Account01.java @@ -6,7 +6,7 @@ import com.mybatisflex.annotation.Table; import java.util.Date; -@Table(value = "tb_account",schema = "flex") +@Table(value = "tb_a01",schema = "flex") public class Account01 { @Id diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java index 02ea99d2..398295a1 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java @@ -1,13 +1,14 @@ package com.mybatisflex.coretest; -import com.mybatisflex.core.dialect.impl.CommonsDialectImpl; import com.mybatisflex.core.dialect.IDialect; import com.mybatisflex.core.dialect.KeywordWrap; import com.mybatisflex.core.dialect.LimitOffsetProcessor; +import com.mybatisflex.core.dialect.impl.CommonsDialectImpl; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; +import com.mybatisflex.core.table.TableManager; import org.junit.Test; import java.util.Arrays; @@ -42,6 +43,36 @@ public class AccountSqlTester { System.out.println(sql); } + @Test + public void testSelectWithSchemaSql01() { + QueryWrapper query = new QueryWrapper() + .select() + .from(ACCOUNT01).leftJoin(ACCOUNT).on(ACCOUNT01.ID.eq(ACCOUNT.ID)) + .where(ACCOUNT01.ID.ge(100)) + .and(ACCOUNT.SEX.eq(1)); + + TableManager.setDynamicTableProcessor(original -> original+"_01"); + TableManager.setDynamicTableProcessor(original -> original+"_01"); + + System.out.println(query.toDebugSQL()); + } + + + @Test + public void testSelectWithSchemaSql02() { + QueryWrapper query = new QueryWrapper() + .select() + .from(ACCOUNT01).as("a1").leftJoin(ACCOUNT).on(ACCOUNT01.ID.eq(ACCOUNT.ID)) + .where(ACCOUNT01.ID.ge(100)) + .and(ACCOUNT.SEX.eq(1)); + + TableManager.setDynamicTableProcessor(original -> original+"_01"); + TableManager.setDynamicTableProcessor(original -> original+"_01"); + + System.out.println(query.toDebugSQL()); + } + + @Test public void testSelectColumnsSql() { QueryWrapper query = new QueryWrapper() 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 5bebbbbf..aae6fe96 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 @@ -21,15 +21,11 @@ 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 com.mybatisflex.core.row.RowUtil; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import javax.sql.DataSource; -import java.util.List; -import static com.mybatisflex.core.query.QueryMethods.select; import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT; import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE; @@ -138,7 +134,7 @@ public class EntityTestStarter { .leftJoin(ACCOUNT).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID)) .where(ARTICLE.ID.ge(0).or(ACCOUNT.ID.ge(0))); - RowUtil.printPretty(Db.selectListByQuery(asWrapper)); +// RowUtil.printPretty(Db.selectListByQuery(asWrapper)); // // List articleDTOS = accountMapper.selectListByQueryAs(asWrapper, ArticleDTO.class); // System.out.println(articleDTOS); @@ -195,15 +191,15 @@ public class EntityTestStarter { // .or(SYS_CONFIG.TYPE.like(word).when(StrChecker.isNotBlank(word))) // ); - List accounts = accountMapper.selectListByQuery( - select().where(ACCOUNT.AGE.ge(18).when(false)) - .and(ACCOUNT.USER_NAME.like("aaaa").when(false) - .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) - .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) - .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) - ) - ); - System.out.println(accounts); +// List accounts = accountMapper.selectListByQuery( +// select().where(ACCOUNT.AGE.ge(18).when(false)) +// .and(ACCOUNT.USER_NAME.like("aaaa").when(false) +// .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) +// .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) +// .or(ACCOUNT.USER_NAME.like("aaaa").when(false)) +// ) +// ); +// System.out.println(accounts); // Page paginate = accountMapper.paginate(1, 10, QueryWrapper.create()); From 43a5e08959929eb5798fd5f297a243b4426e53c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 15:42:35 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E8=A1=A8=E5=90=8D=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/.vitepress/config.ts | 1 + docs/zh/core/dynamic-table.md | 46 +++++++++++++++++++ .../mybatisflex/core/table/TableManager.java | 18 ++++---- .../coretest/AccountSqlTester.java | 8 +++- 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 docs/zh/core/dynamic-table.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 893e1f2a..569da4b2 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -87,6 +87,7 @@ export default defineConfig({ {text: '字段加密', link: '/zh/core/columns-encrypt'}, {text: '字典回写', link: '/zh/core/columns-dict'}, {text: '枚举属性', link: '/zh/core/enum-property'}, + {text: '动态表名', link: '/zh/core/dynamic-table'}, {text: '多租户', link: '/zh/core/multi-tenancy'}, ] }, diff --git a/docs/zh/core/dynamic-table.md b/docs/zh/core/dynamic-table.md new file mode 100644 index 00000000..dcd83620 --- /dev/null +++ b/docs/zh/core/dynamic-table.md @@ -0,0 +1,46 @@ +# 动态表名 + +动态表名指的是用户在对数据进行 增删改查 的时候,传入表名能够根据上下文信息(比如用户信息、应用信息)等,动态修改当前的表。 + +## 使用场景 + +- 1、多租户,不同的租户拥有不同的表 +- 2、分库分表,减轻数据压力 + +## 如何使用 + +在应用启动时,通过调用 `TableManager.setDynamicTableProcessor()` 配置动态表名处理器 `DynamicTableProcessor` 即可,如下代码所示: + +```java +TableManager.setDynamicTableProcessor(new DynamicTableProcessor() { + @Override + public String process(String tableName) { + return tableName + "_01"; + } +}); +``` + +通过以上配置后,我们对数据库进行增删改查,MyBatis-Flex 都会调用 `DynamicTableProcessor.process` 方法,获得最新的表名进行 SQL 构建操作。因此,我们应该在 `process` 方法中, +判断当前的上下文(用户信息、应用信息)等,动态的返回对应的表名。 + +在某些情况下,我们临时修改映射关系,而非通过 `DynamicTableProcessor.process` 方法获取,可以通过如下配置: + +```java +TableManager.setHintTableMapping("tb_account", "tb_account_01") +``` +那么此时,当前线程不再通过 `DynamicTableProcessor` 去获取。 + +## 动态 Schema + +动态 Schema 和动态表名类似,通过 `TableManager.setDynamicSchemaProcessor()` 配置动态 Schema 处理器 `DynamicSchemaProcessor` 即可,如下代码所示: + +```java +TableManager.setDynamicSchemaProcessor(new DynamicSchemaProcessor() { + @Override + public String process(String schema) { + return schema + "_01"; + } +}); +``` + +动态 Schema 的配置,只对使用了注解 `@Table(schema="xxx")` 的 Entity 有效。 \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java index ef97600c..048dc4b6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java @@ -22,21 +22,14 @@ import java.util.Map; public class TableManager { - private static DynamicSchemaProcessor dynamicSchemaProcessor; + private static DynamicTableProcessor dynamicTableProcessor; + private static DynamicSchemaProcessor dynamicSchemaProcessor; private static final ThreadLocal> tableNameMappingTL = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal> schemaMappingTL = ThreadLocal.withInitial(HashMap::new); - public static DynamicSchemaProcessor getDynamicSchemaProcessor() { - return dynamicSchemaProcessor; - } - - public static void setDynamicSchemaProcessor(DynamicSchemaProcessor dynamicSchemaProcessor) { - TableManager.dynamicSchemaProcessor = dynamicSchemaProcessor; - } - public static DynamicTableProcessor getDynamicTableProcessor() { return dynamicTableProcessor; } @@ -45,6 +38,13 @@ public class TableManager { TableManager.dynamicTableProcessor = dynamicTableProcessor; } + public static DynamicSchemaProcessor getDynamicSchemaProcessor() { + return dynamicSchemaProcessor; + } + + public static void setDynamicSchemaProcessor(DynamicSchemaProcessor dynamicSchemaProcessor) { + TableManager.dynamicSchemaProcessor = dynamicSchemaProcessor; + } public static void setHintTableMapping(String tableName, String mappingTable) { tableNameMappingTL.get().put(tableName, mappingTable); diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java index 398295a1..9af5cb83 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/AccountSqlTester.java @@ -6,6 +6,7 @@ import com.mybatisflex.core.dialect.LimitOffsetProcessor; import com.mybatisflex.core.dialect.impl.CommonsDialectImpl; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.table.DynamicTableProcessor; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.table.TableManager; @@ -51,7 +52,12 @@ public class AccountSqlTester { .where(ACCOUNT01.ID.ge(100)) .and(ACCOUNT.SEX.eq(1)); - TableManager.setDynamicTableProcessor(original -> original+"_01"); + TableManager.setDynamicTableProcessor(new DynamicTableProcessor() { + @Override + public String process(String tableName) { + return tableName+"_01"; + } + }); TableManager.setDynamicTableProcessor(original -> original+"_01"); System.out.println(query.toDebugSQL()); From 745bcd06df3488ff09f0b3189403c0551cd89a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 15:55:24 +0800 Subject: [PATCH 05/10] remove FlexXMLConfigBuilder.java --- .../mybatis/FlexSqlSessionFactoryBuilder.java | 28 +- .../core/mybatis/FlexXMLConfigBuilder.java | 409 ------------------ 2 files changed, 27 insertions(+), 410 deletions(-) delete mode 100644 mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexXMLConfigBuilder.java 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 b5c23e97..2502e236 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 @@ -20,6 +20,7 @@ import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.dialect.DbType; import com.mybatisflex.core.dialect.DbTypeUtil; import com.mybatisflex.core.exception.FlexExceptions; +import org.apache.ibatis.builder.xml.XMLConfigBuilder; import org.apache.ibatis.exceptions.ExceptionFactory; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.session.Configuration; @@ -28,14 +29,39 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; +import java.io.Reader; import java.util.Properties; public class FlexSqlSessionFactoryBuilder extends SqlSessionFactoryBuilder { + @Override + public SqlSessionFactory build(Reader reader, String environment, Properties properties) { + try { + // 需要 mybaits v3.5.13+ + // https://github.com/mybatis/mybatis-3/commit/d7826d71a7005a8b4d4e0e7a020db0f6c7e253a4 + XMLConfigBuilder parser = new XMLConfigBuilder(FlexConfiguration.class, reader, environment, properties); + return build(parser.parse()); + } catch (Exception e) { + throw ExceptionFactory.wrapException("Error building SqlSession.", e); + } finally { + ErrorContext.instance().reset(); + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + // Intentionally ignore. Prefer previous error. + } + } + } + + @Override public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { - FlexXMLConfigBuilder parser = new FlexXMLConfigBuilder(inputStream, environment, properties); + // 需要 mybaits v3.5.13+ + // https://github.com/mybatis/mybatis-3/commit/d7826d71a7005a8b4d4e0e7a020db0f6c7e253a4 + XMLConfigBuilder parser = new XMLConfigBuilder(FlexConfiguration.class, inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexXMLConfigBuilder.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexXMLConfigBuilder.java deleted file mode 100644 index b636f5b1..00000000 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexXMLConfigBuilder.java +++ /dev/null @@ -1,409 +0,0 @@ -/** - * 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 org.apache.ibatis.builder.BaseBuilder; -import org.apache.ibatis.builder.BuilderException; -import org.apache.ibatis.builder.xml.XMLMapperBuilder; -import org.apache.ibatis.builder.xml.XMLMapperEntityResolver; -import org.apache.ibatis.datasource.DataSourceFactory; -import org.apache.ibatis.executor.ErrorContext; -import org.apache.ibatis.executor.loader.ProxyFactory; -import org.apache.ibatis.io.Resources; -import org.apache.ibatis.io.VFS; -import org.apache.ibatis.logging.Log; -import org.apache.ibatis.mapping.DatabaseIdProvider; -import org.apache.ibatis.mapping.Environment; -import org.apache.ibatis.parsing.XNode; -import org.apache.ibatis.parsing.XPathParser; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.reflection.DefaultReflectorFactory; -import org.apache.ibatis.reflection.MetaClass; -import org.apache.ibatis.reflection.ReflectorFactory; -import org.apache.ibatis.reflection.factory.ObjectFactory; -import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; -import org.apache.ibatis.session.*; -import org.apache.ibatis.transaction.TransactionFactory; -import org.apache.ibatis.type.JdbcType; - -import javax.sql.DataSource; -import java.io.InputStream; -import java.io.Reader; -import java.util.Properties; - -/** - * @author Clinton Begin - * @author Kazuki Shimizu - */ -public class FlexXMLConfigBuilder extends BaseBuilder { - - private boolean parsed; - private final XPathParser parser; - private String environment; - private final ReflectorFactory localReflectorFactory = new DefaultReflectorFactory(); - - public FlexXMLConfigBuilder(Reader reader) { - this(reader, null, null); - } - - public FlexXMLConfigBuilder(Reader reader, String environment) { - this(reader, environment, null); - } - - public FlexXMLConfigBuilder(Reader reader, String environment, Properties props) { - this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props); - } - - public FlexXMLConfigBuilder(InputStream inputStream) { - this(inputStream, null, null); - } - - public FlexXMLConfigBuilder(InputStream inputStream, String environment) { - this(inputStream, environment, null); - } - - public FlexXMLConfigBuilder(InputStream inputStream, String environment, Properties props) { - this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props); - } - - private FlexXMLConfigBuilder(XPathParser parser, String environment, Properties props) { - // 目前暂时只能通过这里替换 configuration - // 新的版本已经支持自定义 configuration,但需新版本 release: - // 详情 https://github.com/mybatis/mybatis-3/commit/d7826d71a7005a8b4d4e0e7a020db0f6c7e253a4 - super(new FlexConfiguration()); - ErrorContext.instance().resource("SQL Mapper Configuration"); - this.configuration.setVariables(props); - this.parsed = false; - this.environment = environment; - this.parser = parser; - } - - public Configuration parse() { - if (parsed) { - throw new BuilderException("Each XMLConfigBuilder can only be used once."); - } - parsed = true; - parseConfiguration(parser.evalNode("/configuration")); - return configuration; - } - - private void parseConfiguration(XNode root) { - try { - // issue #117 read properties first - propertiesElement(root.evalNode("properties")); - Properties settings = settingsAsProperties(root.evalNode("settings")); - loadCustomVfs(settings); - loadCustomLogImpl(settings); - typeAliasesElement(root.evalNode("typeAliases")); - pluginElement(root.evalNode("plugins")); - objectFactoryElement(root.evalNode("objectFactory")); - objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); - reflectorFactoryElement(root.evalNode("reflectorFactory")); - settingsElement(settings); - // read it after objectFactory and objectWrapperFactory issue #631 - environmentsElement(root.evalNode("environments")); - databaseIdProviderElement(root.evalNode("databaseIdProvider")); - typeHandlerElement(root.evalNode("typeHandlers")); - mapperElement(root.evalNode("mappers")); - } catch (Exception e) { - throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); - } - } - - private Properties settingsAsProperties(XNode context) { - if (context == null) { - return new Properties(); - } - Properties props = context.getChildrenAsProperties(); - // Check that all settings are known to the configuration class - MetaClass metaConfig = MetaClass.forClass(Configuration.class, localReflectorFactory); - for (Object key : props.keySet()) { - if (!metaConfig.hasSetter(String.valueOf(key))) { - throw new BuilderException("The setting " + key + " is not known. Make sure you spelled it correctly (case sensitive)."); - } - } - return props; - } - - private void loadCustomVfs(Properties props) throws ClassNotFoundException { - String value = props.getProperty("vfsImpl"); - if (value != null) { - String[] clazzes = value.split(","); - for (String clazz : clazzes) { - if (!clazz.isEmpty()) { - @SuppressWarnings("unchecked") - Class vfsImpl = (Class)Resources.classForName(clazz); - configuration.setVfsImpl(vfsImpl); - } - } - } - } - - private void loadCustomLogImpl(Properties props) { - Class logImpl = resolveClass(props.getProperty("logImpl")); - configuration.setLogImpl(logImpl); - } - - private void typeAliasesElement(XNode parent) { - if (parent != null) { - for (XNode child : parent.getChildren()) { - if ("package".equals(child.getName())) { - String typeAliasPackage = child.getStringAttribute("name"); - configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage); - } else { - String alias = child.getStringAttribute("alias"); - String type = child.getStringAttribute("type"); - try { - Class clazz = Resources.classForName(type); - if (alias == null) { - typeAliasRegistry.registerAlias(clazz); - } else { - typeAliasRegistry.registerAlias(alias, clazz); - } - } catch (ClassNotFoundException e) { - throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e); - } - } - } - } - } - - private void pluginElement(XNode parent) throws Exception { - if (parent != null) { - for (XNode child : parent.getChildren()) { - String interceptor = child.getStringAttribute("interceptor"); - Properties properties = child.getChildrenAsProperties(); - Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).getDeclaredConstructor().newInstance(); - interceptorInstance.setProperties(properties); - configuration.addInterceptor(interceptorInstance); - } - } - } - - private void objectFactoryElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type"); - Properties properties = context.getChildrenAsProperties(); - ObjectFactory factory = (ObjectFactory) resolveClass(type).getDeclaredConstructor().newInstance(); - factory.setProperties(properties); - configuration.setObjectFactory(factory); - } - } - - private void objectWrapperFactoryElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type"); - ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).getDeclaredConstructor().newInstance(); - configuration.setObjectWrapperFactory(factory); - } - } - - private void reflectorFactoryElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type"); - ReflectorFactory factory = (ReflectorFactory) resolveClass(type).getDeclaredConstructor().newInstance(); - configuration.setReflectorFactory(factory); - } - } - - private void propertiesElement(XNode context) throws Exception { - if (context != null) { - Properties defaults = context.getChildrenAsProperties(); - String resource = context.getStringAttribute("resource"); - String url = context.getStringAttribute("url"); - if (resource != null && url != null) { - throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other."); - } - if (resource != null) { - defaults.putAll(Resources.getResourceAsProperties(resource)); - } else if (url != null) { - defaults.putAll(Resources.getUrlAsProperties(url)); - } - Properties vars = configuration.getVariables(); - if (vars != null) { - defaults.putAll(vars); - } - parser.setVariables(defaults); - configuration.setVariables(defaults); - } - } - - private void settingsElement(Properties props) { - configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL"))); - configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE"))); - configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true)); - configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory"))); - configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false)); - configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false)); - configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true)); - configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true)); - configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false)); - configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE"))); - configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null)); - configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null)); - configuration.setDefaultResultSetType(resolveResultSetType(props.getProperty("defaultResultSetType"))); - configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false)); - configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false)); - configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION"))); - configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER"))); - configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString")); - configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true)); - configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage"))); - configuration.setDefaultEnumTypeHandler(resolveClass(props.getProperty("defaultEnumTypeHandler"))); - configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false)); - configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true)); - configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false)); - configuration.setLogPrefix(props.getProperty("logPrefix")); - configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory"))); - configuration.setShrinkWhitespacesInSql(booleanValueOf(props.getProperty("shrinkWhitespacesInSql"), false)); - configuration.setArgNameBasedConstructorAutoMapping(booleanValueOf(props.getProperty("argNameBasedConstructorAutoMapping"), false)); - configuration.setDefaultSqlProviderType(resolveClass(props.getProperty("defaultSqlProviderType"))); - configuration.setNullableOnForEach(booleanValueOf(props.getProperty("nullableOnForEach"), false)); - } - - private void environmentsElement(XNode context) throws Exception { - if (context != null) { - if (environment == null) { - environment = context.getStringAttribute("default"); - } - for (XNode child : context.getChildren()) { - String id = child.getStringAttribute("id"); - if (isSpecifiedEnvironment(id)) { - TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager")); - DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource")); - DataSource dataSource = dsFactory.getDataSource(); - Environment.Builder environmentBuilder = new Environment.Builder(id) - .transactionFactory(txFactory) - .dataSource(dataSource); - configuration.setEnvironment(environmentBuilder.build()); - break; - } - } - } - } - - private void databaseIdProviderElement(XNode context) throws Exception { - DatabaseIdProvider databaseIdProvider = null; - if (context != null) { - String type = context.getStringAttribute("type"); - // awful patch to keep backward compatibility - if ("VENDOR".equals(type)) { - type = "DB_VENDOR"; - } - Properties properties = context.getChildrenAsProperties(); - databaseIdProvider = (DatabaseIdProvider) resolveClass(type).getDeclaredConstructor().newInstance(); - databaseIdProvider.setProperties(properties); - } - Environment environment = configuration.getEnvironment(); - if (environment != null && databaseIdProvider != null) { - String databaseId = databaseIdProvider.getDatabaseId(environment.getDataSource()); - configuration.setDatabaseId(databaseId); - } - } - - private TransactionFactory transactionManagerElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type"); - Properties props = context.getChildrenAsProperties(); - TransactionFactory factory = (TransactionFactory) resolveClass(type).getDeclaredConstructor().newInstance(); - factory.setProperties(props); - return factory; - } - throw new BuilderException("Environment declaration requires a TransactionFactory."); - } - - private DataSourceFactory dataSourceElement(XNode context) throws Exception { - if (context != null) { - String type = context.getStringAttribute("type"); - Properties props = context.getChildrenAsProperties(); - DataSourceFactory factory = (DataSourceFactory) resolveClass(type).getDeclaredConstructor().newInstance(); - factory.setProperties(props); - return factory; - } - throw new BuilderException("Environment declaration requires a DataSourceFactory."); - } - - private void typeHandlerElement(XNode parent) { - if (parent != null) { - for (XNode child : parent.getChildren()) { - if ("package".equals(child.getName())) { - String typeHandlerPackage = child.getStringAttribute("name"); - typeHandlerRegistry.register(typeHandlerPackage); - } else { - String javaTypeName = child.getStringAttribute("javaType"); - String jdbcTypeName = child.getStringAttribute("jdbcType"); - String handlerTypeName = child.getStringAttribute("handler"); - Class javaTypeClass = resolveClass(javaTypeName); - JdbcType jdbcType = resolveJdbcType(jdbcTypeName); - Class typeHandlerClass = resolveClass(handlerTypeName); - if (javaTypeClass != null) { - if (jdbcType == null) { - typeHandlerRegistry.register(javaTypeClass, typeHandlerClass); - } else { - typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass); - } - } else { - typeHandlerRegistry.register(typeHandlerClass); - } - } - } - } - } - - private void mapperElement(XNode parent) throws Exception { - if (parent != null) { - for (XNode child : parent.getChildren()) { - if ("package".equals(child.getName())) { - String mapperPackage = child.getStringAttribute("name"); - configuration.addMappers(mapperPackage); - } else { - String resource = child.getStringAttribute("resource"); - String url = child.getStringAttribute("url"); - String mapperClass = child.getStringAttribute("class"); - if (resource != null && url == null && mapperClass == null) { - ErrorContext.instance().resource(resource); - try(InputStream inputStream = Resources.getResourceAsStream(resource)) { - XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); - mapperParser.parse(); - } - } else if (resource == null && url != null && mapperClass == null) { - ErrorContext.instance().resource(url); - try(InputStream inputStream = Resources.getUrlAsStream(url)){ - XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments()); - mapperParser.parse(); - } - } else if (resource == null && url == null && mapperClass != null) { - Class mapperInterface = Resources.classForName(mapperClass); - configuration.addMapper(mapperInterface); - } else { - throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one."); - } - } - } - } - } - - private boolean isSpecifiedEnvironment(String id) { - if (environment == null) { - throw new BuilderException("No environment specified."); - } - if (id == null) { - throw new BuilderException("Environment requires an id attribute."); - } - return environment.equals(id); - } - -} From 0a348038ab9322a51bf3f96704f65c57495dfa09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 17:34:47 +0800 Subject: [PATCH 06/10] v1.3.3 release (^.^)YYa!! --- mybatis-flex-annotation/pom.xml | 2 +- mybatis-flex-codegen/pom.xml | 4 ++-- mybatis-flex-core/pom.xml | 6 +++--- .../src/main/java/com/mybatisflex/core/FlexConsts.java | 2 +- mybatis-flex-processor/pom.xml | 4 ++-- mybatis-flex-solon-plugin/pom.xml | 4 ++-- mybatis-flex-spring-boot-starter/pom.xml | 4 ++-- mybatis-flex-spring/pom.xml | 4 ++-- mybatis-flex-test/mybatis-flex-native-test/pom.xml | 4 ++-- mybatis-flex-test/mybatis-flex-spring-boot-test/pom.xml | 4 ++-- mybatis-flex-test/mybatis-flex-spring-test/pom.xml | 6 +++--- mybatis-flex-test/pom.xml | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/mybatis-flex-annotation/pom.xml b/mybatis-flex-annotation/pom.xml index 27b70186..a5e5383d 100644 --- a/mybatis-flex-annotation/pom.xml +++ b/mybatis-flex-annotation/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 diff --git a/mybatis-flex-codegen/pom.xml b/mybatis-flex-codegen/pom.xml index 4ed08b72..b382d94d 100644 --- a/mybatis-flex-codegen/pom.xml +++ b/mybatis-flex-codegen/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -27,7 +27,7 @@ com.mybatis-flex mybatis-flex-spring - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-core/pom.xml b/mybatis-flex-core/pom.xml index 13a56117..1affdc4d 100644 --- a/mybatis-flex-core/pom.xml +++ b/mybatis-flex-core/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -22,13 +22,13 @@ com.mybatis-flex mybatis-flex-annotation - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexConsts.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexConsts.java index 7a7d766c..dd584ca2 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexConsts.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexConsts.java @@ -20,7 +20,7 @@ package com.mybatisflex.core; */ public class FlexConsts { public static final String NAME = "MyBatis-Flex"; - public static final String VERSION = "1.3.2"; + public static final String VERSION = "1.3.3"; public static final String DEFAULT_PRIMARY_FIELD = "id"; diff --git a/mybatis-flex-processor/pom.xml b/mybatis-flex-processor/pom.xml index 803ddf6e..066e5c22 100644 --- a/mybatis-flex-processor/pom.xml +++ b/mybatis-flex-processor/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -20,7 +20,7 @@ com.mybatis-flex mybatis-flex-annotation - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-solon-plugin/pom.xml b/mybatis-flex-solon-plugin/pom.xml index c8d5a63c..68b3ea07 100644 --- a/mybatis-flex-solon-plugin/pom.xml +++ b/mybatis-flex-solon-plugin/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -21,7 +21,7 @@ com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-spring-boot-starter/pom.xml b/mybatis-flex-spring-boot-starter/pom.xml index cb4f7680..fe486abb 100644 --- a/mybatis-flex-spring-boot-starter/pom.xml +++ b/mybatis-flex-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -21,7 +21,7 @@ com.mybatis-flex mybatis-flex-spring - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-spring/pom.xml b/mybatis-flex-spring/pom.xml index f6ad65fa..39e5342b 100644 --- a/mybatis-flex-spring/pom.xml +++ b/mybatis-flex-spring/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -20,7 +20,7 @@ com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-test/mybatis-flex-native-test/pom.xml b/mybatis-flex-test/mybatis-flex-native-test/pom.xml index d195fb13..91b20d5f 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/pom.xml +++ b/mybatis-flex-test/mybatis-flex-native-test/pom.xml @@ -5,7 +5,7 @@ mybatis-flex-test com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -20,7 +20,7 @@ com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/pom.xml b/mybatis-flex-test/mybatis-flex-spring-boot-test/pom.xml index 2616acfc..f12f9ebb 100644 --- a/mybatis-flex-test/mybatis-flex-spring-boot-test/pom.xml +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/pom.xml @@ -5,7 +5,7 @@ mybatis-flex-test com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -21,7 +21,7 @@ com.mybatis-flex mybatis-flex-spring-boot-starter - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-test/mybatis-flex-spring-test/pom.xml b/mybatis-flex-test/mybatis-flex-spring-test/pom.xml index a26f9fe1..e39536a3 100644 --- a/mybatis-flex-test/mybatis-flex-spring-test/pom.xml +++ b/mybatis-flex-test/mybatis-flex-spring-test/pom.xml @@ -5,7 +5,7 @@ mybatis-flex-test com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -20,13 +20,13 @@ com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-spring - 1.3.2 + 1.3.3 diff --git a/mybatis-flex-test/pom.xml b/mybatis-flex-test/pom.xml index a2090d8a..ac08c048 100644 --- a/mybatis-flex-test/pom.xml +++ b/mybatis-flex-test/pom.xml @@ -5,7 +5,7 @@ parent com.mybatis-flex - 1.3.2 + 1.3.3 4.0.0 @@ -59,7 +59,7 @@ com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 From ede1636c94562e16230835432b602740e344fa28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 17:34:53 +0800 Subject: [PATCH 07/10] v1.3.3 release (^.^)YYa!! --- deploy.sh | 2 -- docs/zh/intro/getting-started.md | 6 +++--- docs/zh/intro/maven.md | 14 +++++++------- docs/zh/others/apt.md | 2 +- docs/zh/others/codegen.md | 2 +- pom.xml | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) delete mode 100755 deploy.sh diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index 9c148e26..00000000 --- a/deploy.sh +++ /dev/null @@ -1,2 +0,0 @@ -# gpgconf --kill gpg-agent - mvn deploy -pl "parent,mybatis-flex-annotation,mybatis-flex-codegen,mybatis-flex-core,mybatis-flex-spring,mybatis-flex-spring-boot-starter" -e -P release \ No newline at end of file diff --git a/docs/zh/intro/getting-started.md b/docs/zh/intro/getting-started.md index fffa7572..b7949782 100644 --- a/docs/zh/intro/getting-started.md +++ b/docs/zh/intro/getting-started.md @@ -27,12 +27,12 @@ Maven示例: com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 provided ``` @@ -46,7 +46,7 @@ Gradle示例: ```groovy // file: build.gradle ext { - mybatis_flex_version = '1.3.2' + mybatis_flex_version = '1.3.3' } dependencies { implementation("com.mybatis-flex:mybatis-flex-core:${mybatis_flex_version}") diff --git a/docs/zh/intro/maven.md b/docs/zh/intro/maven.md index fc1d6f56..250c6229 100644 --- a/docs/zh/intro/maven.md +++ b/docs/zh/intro/maven.md @@ -12,12 +12,12 @@ com.mybatis-flex mybatis-flex-core - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 provided ``` @@ -28,12 +28,12 @@ com.mybatis-flex mybatis-flex-spring - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 provided `````` @@ -44,12 +44,12 @@ com.mybatis-flex mybatis-flex-spring-boot-starter - 1.3.2 + 1.3.3 com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 provided ``` @@ -70,7 +70,7 @@ com.mybatis-flex mybatis-flex-processor - 1.3.2 + 1.3.3 diff --git a/docs/zh/others/apt.md b/docs/zh/others/apt.md index 83db7798..3b464c34 100644 --- a/docs/zh/others/apt.md +++ b/docs/zh/others/apt.md @@ -179,7 +179,7 @@ processor.baseMapperClass=com.domain.mapper.MyBaseMapper ``` dependencies { ... - annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:1.3.2' + annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:1.3.3' } ``` diff --git a/docs/zh/others/codegen.md b/docs/zh/others/codegen.md index 9beed72f..b8763f48 100644 --- a/docs/zh/others/codegen.md +++ b/docs/zh/others/codegen.md @@ -10,7 +10,7 @@ com.mybatis-flex mybatis-flex-codegen - 1.3.2 + 1.3.3 ``` diff --git a/pom.xml b/pom.xml index 49671dd9..30dc4c6b 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.mybatis-flex parent pom - 1.3.2 + 1.3.3 mybatis-flex https://mybatis-flex.com From 7bf23281275c49ed5445842108397c0a4b9f7ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 17:34:58 +0800 Subject: [PATCH 08/10] v1.3.3 release (^.^)YYa!! --- changes.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/changes.txt b/changes.txt index a2f25361..c2dd2e0e 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,21 @@ +mybatis-flex v1.3.3 20230530: +新增:添加动态表名和动态 Schema 的支持 #I6VRMF #I6WS3E #I72X21 +新增:添加 @Table(schema=xxx) 配置的支持 #I6VD6U +新增:Left join 等关联查询时,支持直接赋值对象属性的功能 +新增:添加 QueryWrapper.toDebugSQL() 方法,方便用于调试 +优化:Entity 父子类定义了相同字段时,应已子类优先 +优化:对逻辑删除定义的非 Number 和 Bool 类型的 SQL 构建优化 +优化:升级 MyBatis 到 3.5.13 最新版本 +优化:升级 MyBatis 后,删除冗余的 FlexXMLConfigBuilder 实现 +优化:升级 solon 版本,以支持原生编译功能,感谢 @西东 +修复:分页查询在 left join 优化是,错误移除的问题 +文档:优化 多表查询 的相关文档 +文档:添加枚举属性构建 QueryWrapper 的相关文档 +文档:添加自定义 MyBatis 的 Configuration 的文档 +文档:添加动态表名和动态 Schema 的相关文档 + + + mybatis-flex v1.3.2 20230528: 新增:select (field1 * field2 * 100) as xxx from ... 的 SQL 构建场景 优化:ClassUtil.wrap 方法修改为 getWrapType From 718c430421544cc6aa311e13a9e018162b776bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 17:38:04 +0800 Subject: [PATCH 09/10] v1.3.3 release (^.^)YYa!! --- .../mybatisflex/spring/FlexSqlSessionFactoryBean.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSqlSessionFactoryBean.java b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSqlSessionFactoryBean.java index de36da72..b0336c84 100644 --- a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSqlSessionFactoryBean.java +++ b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSqlSessionFactoryBean.java @@ -19,7 +19,7 @@ import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; -import com.mybatisflex.core.mybatis.FlexXMLConfigBuilder; +import org.apache.ibatis.builder.xml.XMLConfigBuilder; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.cache.Cache; import org.apache.ibatis.executor.ErrorContext; @@ -492,8 +492,7 @@ public class FlexSqlSessionFactoryBean extends SqlSessionFactoryBean final Configuration targetConfiguration; -// XMLConfigBuilder xmlConfigBuilder = null; - FlexXMLConfigBuilder xmlConfigBuilder = null; + XMLConfigBuilder xmlConfigBuilder = null; if (this.configuration != null) { targetConfiguration = this.configuration; if (targetConfiguration.getVariables() == null) { @@ -502,12 +501,11 @@ public class FlexSqlSessionFactoryBean extends SqlSessionFactoryBean targetConfiguration.getVariables().putAll(this.configurationProperties); } } else if (this.configLocation != null) { -// xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties); - xmlConfigBuilder = new FlexXMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties); + xmlConfigBuilder = new XMLConfigBuilder(FlexConfiguration.class, this.configLocation.getInputStream(), null, this.configurationProperties); targetConfiguration = xmlConfigBuilder.getConfiguration(); } else { LOGGER.debug( - () -> "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration"); + () -> "Property 'configuration' or 'configLocation' not specified, using default Flex Configuration"); // targetConfiguration = new Configuration(); targetConfiguration = new FlexConfiguration(); Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables); From e1757a3cf5249fb586716a0d603fe3300f8de04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=80=E6=BA=90=E6=B5=B7=E5=93=A5?= Date: Tue, 30 May 2023 18:32:02 +0800 Subject: [PATCH 10/10] fixed schema error in queryWrapper --- .../com/mybatisflex/core/provider/EntitySqlProvider.java | 6 +++--- .../src/main/java/com/mybatisflex/core/query/CPI.java | 9 ++++++++- .../java/com/mybatisflex/core/query/QueryWrapper.java | 9 ++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java index 2c5f1072..6429f1aa 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java @@ -175,7 +175,7 @@ public class EntitySqlProvider { } TableInfo tableInfo = ProviderUtil.getTableInfo(context); - CPI.setFromIfNecessary(queryWrapper, tableInfo.getTableName()); + CPI.setFromIfNecessary(queryWrapper, tableInfo.getSchema(), tableInfo.getTableName()); tableInfo.appendConditions(null, queryWrapper); ProviderUtil.setSqlArgs(params, CPI.getValueArray(queryWrapper)); @@ -339,7 +339,7 @@ public class EntitySqlProvider { tableInfo.appendConditions(null, queryWrapper); CPI.setSelectColumnsIfNecessary(queryWrapper, tableInfo.getDefaultQueryColumn()); - CPI.setFromIfNecessary(queryWrapper, tableInfo.getTableName()); + CPI.setFromIfNecessary(queryWrapper, tableInfo.getSchema(), tableInfo.getTableName()); } Object[] values = CPI.getValueArray(queryWrapper); @@ -366,7 +366,7 @@ public class EntitySqlProvider { for (TableInfo tableInfo : tableInfos) { tableInfo.appendConditions(null, queryWrapper); - CPI.setFromIfNecessary(queryWrapper, tableInfo.getTableName()); + CPI.setFromIfNecessary(queryWrapper, tableInfo.getSchema(), tableInfo.getTableName()); } Object[] values = CPI.getValueArray(queryWrapper); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java index e61e0198..29821c5b 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java @@ -162,7 +162,7 @@ public class CPI { return queryWrapper.getEndFragments(); } - public static void setEndFragments(QueryWrapper queryWrapper,List endFragments) { + public static void setEndFragments(QueryWrapper queryWrapper, List endFragments) { queryWrapper.setEndFragments(endFragments); } @@ -200,6 +200,13 @@ public class CPI { } } + public static void setFromIfNecessary(QueryWrapper queryWrapper, String schema, String tableName) { + if (StringUtil.isNotBlank(tableName) + && CollectionUtil.isEmpty(queryWrapper.getQueryTables())) { + queryWrapper.from(new QueryTable(schema, tableName)); + } + } + public static boolean containsTable(QueryCondition condition, String... tables) { return condition != null && condition.containsTable(tables); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java index f4014c21..7413d70c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java @@ -55,7 +55,14 @@ public class QueryWrapper extends BaseQueryWrapper { if (StringUtil.isBlank(table)) { throw new IllegalArgumentException("table must not be null or blank."); } - from(new QueryTable(table)); + int indexOf = table.indexOf("."); + if (indexOf > 0) { + String schema = table.substring(0, indexOf); + table = table.substring(indexOf + 1); + from(new QueryTable(schema, table)); + } else { + from(new QueryTable(table)); + } } return this; }