diff --git a/docs/zh/others/apt.md b/docs/zh/others/apt.md index 61e12eba..db3bcaf7 100644 --- a/docs/zh/others/apt.md +++ b/docs/zh/others/apt.md @@ -18,6 +18,7 @@ MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编 | processor.enable | 全局启用apt开关 | true/false | true | | processor.stopBubbling | 是否停止向上级合并配 | true/false | false | | processor.genPath | APT 代码生成路径 | 合法的绝对或相对路径 | target/generated-sources/annotations | +| processor.charset | APT 代码生成文件字符集 | UTF-8 | target/generated-sources/annotations | | processor.allInTables.enable | 是否所有的类都生成在 Tables 类里 | true/false | false | | processor.allInTables.package | Tables 类名 | 合法的包名 | ${entityPackage}.table | | processor.allInTables.className | Tables 类名 | 合法的类名 | Tables | diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java index 4e313807..a329919a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java @@ -82,4 +82,18 @@ public final class FlexAssert { } } -} \ No newline at end of file + /** + * 断言传入的数组内容不能为 null 或者 空 + */ + public static void assertAreNotNull(T[] elements, String msg, Object params) { + if (elements == null || elements.length == 0) { + throw FlexExceptions.wrap(msg, params); + } + for (T element : elements) { + if (element == null) { + throw FlexExceptions.wrap(msg, params); + } + } + } + +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexExceptions.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexExceptions.java index cf335bf2..2d196564 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexExceptions.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexExceptions.java @@ -15,6 +15,8 @@ */ package com.mybatisflex.core.exception; +import com.mybatisflex.core.exception.locale.Localizable; + /** * MybatisFlexException 异常封装类 */ @@ -61,41 +63,8 @@ public final class FlexExceptions { return new MybatisFlexException(String.format(msg, params)); } - - /** - * 断言 condition 必须为 true - * - * @param condition 条件 - * @param msg 消息 - * @param params 消息参数 - */ - public static void assertTrue(boolean condition, String msg, Object... params) { - if (!condition) { - throw wrap(msg, params); - } - } - - - /** - * 断言传入的内容不能为 null - */ - public static void assertNotNull(Object object, String msg, Object params) { - assertTrue(object != null, msg, params); - } - - - /** - * 断言传入的数组内容不能为 null 或者 空 - */ - public static void assertAreNotNull(T[] elements, String msg, Object params) { - if (elements == null || elements.length == 0) { - throw wrap(msg, params); - } - for (T element : elements) { - if (element == null) { - throw wrap(msg, params); - } - } + public static MybatisFlexException wrap(Localizable pattern, Object... args) { + return new MybatisFlexException(pattern, args); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/MybatisFlexException.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/MybatisFlexException.java index a18b3f13..bc26fa69 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/MybatisFlexException.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/MybatisFlexException.java @@ -15,10 +15,23 @@ */ package com.mybatisflex.core.exception; +import com.mybatisflex.core.exception.locale.Localizable; + +import java.text.MessageFormat; +import java.util.Locale; + public class MybatisFlexException extends RuntimeException { private static final long serialVersionUID = 1L; + private Localizable pattern; + private Object[] arguments; + + public MybatisFlexException(Localizable pattern, Object... arguments) { + this.pattern = pattern; + this.arguments = arguments; + } + public MybatisFlexException(String message) { super(message); } @@ -31,5 +44,19 @@ public class MybatisFlexException extends RuntimeException { super(cause); } + @Override + public String getMessage() { + return getMessage(Locale.CHINESE); + } + + @Override + public String getLocalizedMessage() { + return getMessage(Locale.getDefault()); + } + + private String getMessage(Locale locale) { + String localizedString = pattern.getLocalizedString(locale); + return MessageFormat.format(localizedString, arguments); + } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/Localizable.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/Localizable.java new file mode 100644 index 00000000..f26a4de7 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/Localizable.java @@ -0,0 +1,45 @@ +/* + * 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.exception.locale; + +import java.io.Serializable; +import java.util.Locale; + +/** + * 可本地化字符串接口。 + * + * @author 王帅 + * @since 2023-07-26 + */ +public interface Localizable extends Serializable { + + /** + * 获取源(非本地化)字符串。 + * + * @return 源字符串 + */ + String getSourceString(); + + /** + * 获取本地化字符串。 + * + * @param locale 要获取字符串的区域 + * @return 本地化字符串或源字符串(如果没有可用的本地化版本) + */ + String getLocalizedString(Locale locale); + +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java new file mode 100644 index 00000000..031c9442 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.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.exception.locale; + +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * 异常消息中使用的本地化消息格式的枚举。 + * + * @author 王帅 + * @since 2023-07-26 + */ +public enum LocalizedFormats implements Localizable { + + OBJECT_NULL("{0} can not be null."); + + private final String sourceFormat; + + LocalizedFormats(String sourceFormat) { + this.sourceFormat = sourceFormat; + } + + @Override + public String getSourceString() { + return this.sourceFormat; + } + + @Override + public String getLocalizedString(final Locale locale) { + try { + // 本地化消息路径 + String path = LocalizedFormats.class.getName().replace(".", "/"); + // 获取多语言本地化消息信息文件 + ResourceBundle bundle = ResourceBundle.getBundle("assets/" + path, locale); + // 获取当前语言的消息格式 + if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) { + return bundle.getString(toString()); + } + } catch (MissingResourceException mre) { + mre.printStackTrace(); + // do nothing here. + } + // 如果没有该语言的本地化消息,则返回源消息字符串 + return sourceFormat; + } + +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/package-info.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/package-info.java new file mode 100644 index 00000000..4d0366c3 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/package-info.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.exception.locale; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java index cc55732a..486d6ab5 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/AbstractLogicDeleteProcessor.java @@ -47,20 +47,6 @@ public abstract class AbstractLogicDeleteProcessor implements LogicDeleteProcess , getLogicNormalValue())); } - /** - * 获取逻辑删除列未删除标记值。 - * - * @return 未删除标记值 - */ - public abstract Object getLogicNormalValue(); - - /** - * 获取逻辑删除列删除时标记值。 - * - * @return 删除时标记值 - */ - public abstract Object getLogicDeletedValue(); - } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java new file mode 100644 index 00000000..40f041fa --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java @@ -0,0 +1,67 @@ +/* + * 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.logicdelete.impl; + +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.dialect.IDialect; +import com.mybatisflex.core.exception.FlexAssert; +import com.mybatisflex.core.logicdelete.AbstractLogicDeleteProcessor; +import com.mybatisflex.core.table.IdInfo; +import com.mybatisflex.core.table.TableInfo; + +import java.util.List; + +import static com.mybatisflex.core.constant.SqlConsts.EQUALS; + +/** + * 主键逻辑删除处理器。 + * + * @author 王帅 + * @see I7O1VV + * @since 2023-07-26 + */ +public class PrimaryKeyLogicDeleteProcessor extends AbstractLogicDeleteProcessor { + + @Override + public String buildLogicDeletedSet(String logicColumn, TableInfo tableInfo, IDialect dialect) { + List primaryKeyList = tableInfo.getPrimaryKeyList(); + FlexAssert.notEmpty(primaryKeyList, "Must have one primary key."); + String column = primaryKeyList.get(0).getColumn(); + return dialect.wrap(logicColumn) + EQUALS + dialect.wrap(column); + } + + /** + * 正常未删除的值为 0 (或者可配置为其他值)。 + */ + @Override + public Object getLogicNormalValue() { + Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete(); + if (normalValueOfLogicDelete instanceof Number) { + return normalValueOfLogicDelete; + } + return 0; + } + + /** + * 逻辑删除后,则更新逻辑删除字段值为主键的值。 + */ + @Override + public Object getLogicDeletedValue() { + return null; + } + +} 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 fb8dc5a9..4661d83f 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 @@ -18,7 +18,6 @@ package com.mybatisflex.core.provider; import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.dialect.DialectFactory; import com.mybatisflex.core.exception.FlexAssert; -import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.QueryTable; import com.mybatisflex.core.query.QueryWrapper; @@ -240,7 +239,7 @@ public class EntitySqlProvider { Object[] primaryValues = tableInfo.buildPkSqlArgs(entity); Object[] tenantIdArgs = tableInfo.buildTenantIdArgs(); - FlexExceptions.assertAreNotNull(primaryValues, "The value of primary key must not be null, entity[%s]", entity); + FlexAssert.assertAreNotNull(primaryValues, "The value of primary key must not be null, entity[%s]", entity); ProviderUtil.setSqlArgs(params, ArrayUtil.concat(updateValues, primaryValues, tenantIdArgs)); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java index 5f036516..21d7dba6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java @@ -18,7 +18,6 @@ package com.mybatisflex.core.provider; import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.dialect.DialectFactory; import com.mybatisflex.core.exception.FlexAssert; -import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.row.Row; @@ -247,7 +246,7 @@ public class RowSqlProvider { Object[] primaryValues = tableInfo.buildPkSqlArgs(entity); Object[] tenantIdArgs = tableInfo.buildTenantIdArgs(); - FlexExceptions.assertAreNotNull(primaryValues, "The value of primary key must not be null, entity[%s]", entity); + FlexAssert.assertAreNotNull(primaryValues, "The value of primary key must not be null, entity[%s]", entity); ProviderUtil.setSqlArgs(params, ArrayUtil.concat(updateValues, primaryValues, tenantIdArgs)); diff --git a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties new file mode 100644 index 00000000..e6ad24ae --- /dev/null +++ b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties @@ -0,0 +1 @@ +OBJECT_NULL={0} can not be null. diff --git a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties new file mode 100644 index 00000000..f910a9bb --- /dev/null +++ b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties @@ -0,0 +1 @@ +OBJECT_NULL={0} \u4E0D\u80FD\u4E3A null \u503C\u3002 diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LocaleFormatTest.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LocaleFormatTest.java new file mode 100644 index 00000000..11ef72c4 --- /dev/null +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LocaleFormatTest.java @@ -0,0 +1,34 @@ +/* + * 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.coretest; + +import com.mybatisflex.core.exception.FlexExceptions; +import com.mybatisflex.core.exception.locale.LocalizedFormats; +import org.junit.Test; + +/** + * @author 王帅 + * @since 2023-07-26 + */ +public class LocaleFormatTest { + + @Test + public void test() { + throw FlexExceptions.wrap(LocalizedFormats.OBJECT_NULL, "primaryValues"); + } + +} diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java index 888719aa..80d56ffa 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LogicDeleteTest.java @@ -20,6 +20,8 @@ import com.mybatisflex.core.dialect.DialectFactory; import com.mybatisflex.core.dialect.IDialect; import com.mybatisflex.core.logicdelete.LogicDeleteProcessor; import com.mybatisflex.core.logicdelete.impl.*; +import com.mybatisflex.core.table.TableInfo; +import com.mybatisflex.core.table.TableInfoFactory; import org.junit.Test; /** @@ -41,12 +43,14 @@ public class LogicDeleteTest { print("IntegerLogicDeleteProcessor", new IntegerLogicDeleteProcessor()); print("DateTimeLogicDeleteProcessor", new DateTimeLogicDeleteProcessor()); print("TimeStampLogicDeleteProcessor", new TimeStampLogicDeleteProcessor()); + print("PrimaryKeyLogicDeleteProcessor", new PrimaryKeyLogicDeleteProcessor()); } public void print(String type, LogicDeleteProcessor processor) { System.out.println("===== " + type + " ====="); - System.out.println(processor.buildLogicDeletedSet(logicColumn, null, dialect)); - System.out.println(processor.buildLogicNormalCondition(logicColumn, null, dialect)); + TableInfo tableInfo = TableInfoFactory.ofEntityClass(Account.class); + System.out.println(processor.buildLogicDeletedSet(logicColumn, tableInfo, dialect)); + System.out.println(processor.buildLogicNormalCondition(logicColumn, tableInfo, dialect)); } -} \ No newline at end of file +} diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java index 780b20dc..9a6e39bc 100644 --- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java +++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/MybatisFlexProcessor.java @@ -45,7 +45,6 @@ import java.io.PrintWriter; import java.io.Writer; import java.math.BigDecimal; import java.math.BigInteger; -import java.nio.file.Files; import java.sql.Time; import java.sql.Timestamp; import java.time.*; @@ -383,7 +382,7 @@ public class MybatisFlexProcessor extends AbstractProcessor { return; } - writer = new PrintWriter(Files.newOutputStream(genJavaFile.toPath())); + writer = new PrintWriter(genJavaFile, configuration.get(ConfigurationKey.CHARSET)); writer.write(genContent); writer.flush(); } catch (IOException e) { diff --git a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java index ae76ebd9..40f4488f 100644 --- a/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java +++ b/mybatis-flex-processor/src/main/java/com/mybatisflex/processor/config/ConfigurationKey.java @@ -29,6 +29,11 @@ public enum ConfigurationKey { */ ENABLE("processor.enable", ""), + /** + * 生成文件的字符集。 + */ + CHARSET("processor.charset", "UTF-8"), + /** * APT 代码生成路径。 */ diff --git a/pom.xml b/pom.xml index 3a363d93..f4f42959 100644 --- a/pom.xml +++ b/pom.xml @@ -198,11 +198,6 @@ **/* - - - *.properties - -