diff --git a/docs/zh/core/enum-property.md b/docs/zh/core/enum-property.md index ee59eb2c..bbc8a5d6 100644 --- a/docs/zh/core/enum-property.md +++ b/docs/zh/core/enum-property.md @@ -8,7 +8,7 @@ public class Account{ @Id(keyType = KeyType.Auto) private Long id; - + private TypeEnum typeEnum; } ``` @@ -30,26 +30,56 @@ public enum TypeEnum { @EnumValue private int code; - + private String desc; TypeEnum(int code, String desc) { this.code = code; this.desc = desc; } - + //getter } ``` +```java + +@AllArgsConstructor +public enum EnableEnum { + /** + * 启用 + */ + ENABLE(1, "启用"), + /** + * 禁用 + */ + DISABLE(0, "禁用"), + ; + private final int code; + private final String desc; + + @EnumValue + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} + +``` + 通过注解 `@EnumValue` 为 `code` 属性标注后,当我们保存 Account 内容到数据库时,MyBatis-Flex 会自动使用 `code` 属性值进行保存,同时在读取数据库内容的时候,MyBatis-Flex 自动把数据库的值转换为 `TypeEnum` 枚举。 **注意事项** - 1、@EnumValue 注解标识的属性,要求必须是 public 修饰,或者有 get 方法。 +- 2、@EnumValue 注解标识支持在 get 方法使用注解。 +- 3、枚举注解优先级。 优先取字段上的注解。如果字段没有注解,则会找方法上的注解,如果枚举类当前方法没有注解,则会去找父类的方法寻找存在注解的方法。 -- 2、当配置了 @EnumValue 时,QueryWrapper 构建时,传入枚举,自动使用该值进行 SQL 参数拼接。例如: +- 4、当配置了 @EnumValue 时,QueryWrapper 构建时,传入枚举,自动使用该值进行 SQL 参数拼接。例如: ```java QueryWrapper query = QueryWrapper.create(); @@ -63,4 +93,5 @@ query.select().from(ACCOUNT) select * from tb_account where type_enum = 1 ``` - + + diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java index 50ef61cd..fdae80f0 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/EnumValue.java @@ -22,7 +22,7 @@ import java.lang.annotation.*; */ @Documented @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD}) +@Target({ElementType.FIELD, ElementType.METHOD}) public @interface EnumValue { } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/ConsoleMessageCollector.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/ConsoleMessageCollector.java index 255190f9..930f2d0c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/ConsoleMessageCollector.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/audit/ConsoleMessageCollector.java @@ -18,12 +18,18 @@ package com.mybatisflex.core.audit; public class ConsoleMessageCollector implements MessageCollector { - private SqlDebugPrinter printer = (sql, dsName, tookTimeMillis) -> { + private SqlDebugPrinter printer = (sql, tookTimeMillis) -> { + if (tookTimeMillis != null) { + System.out.println("Flex exec sql took " + tookTimeMillis + " ms >>> " + sql); + } else { + System.out.println("Flex exec sql >>> " + sql); + } + }; + + private SqlDebugExtPrinter extPrinter = (sql, dsName, tookTimeMillis) -> { StringBuilder buffer = new StringBuilder(); buffer.append("Flex exec"); - if (dsName != null) { - buffer.append("dsName >>> ").append(dsName); - } + buffer.append("dsName >>> ").append(dsName); if (tookTimeMillis != null) { buffer.append(" sql took ").append(tookTimeMillis).append(" ms >>> ").append(sql); } else { @@ -39,13 +45,29 @@ public class ConsoleMessageCollector implements MessageCollector { this.printer = printer; } + + public ConsoleMessageCollector(SqlDebugExtPrinter printer) { + this.extPrinter = printer; + } + @Override public void collect(AuditMessage message) { - printer.print(message.getFullSql(), message.getDsName(), message.getElapsedTime()); + if (message.getDsName() == null) { + printer.print(message.getFullSql(), message.getElapsedTime()); + } else { + extPrinter.print(message.getFullSql(), message.getDsName(), message.getElapsedTime()); + } } public interface SqlDebugPrinter { + void print(String sql, Long tookTimeMillis); + + } + + + public interface SqlDebugExtPrinter { + void print(String sql, String dsName, Long tookTimeMillis); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java index 7a4276c6..649ebb8b 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/handler/CompositeEnumTypeHandler.java @@ -22,19 +22,29 @@ import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public class CompositeEnumTypeHandler> implements TypeHandler { private final TypeHandler delegate; public CompositeEnumTypeHandler(Class enumClass) { + boolean isNotFound = false; List enumDbValueFields = ClassUtil.getAllFields(enumClass, f -> f.getAnnotation(EnumValue.class) != null); if (enumDbValueFields.isEmpty()) { + List enumDbValueMethods = ClassUtil.getAllMethods(enumClass, m -> m.getAnnotation(EnumValue.class) != null); + if (enumDbValueMethods.isEmpty()) { + isNotFound = true; + } + } + if (isNotFound) { delegate = new EnumTypeHandler<>(enumClass); } else { delegate = new FlexEnumTypeHandler<>(enumClass); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/EnumWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/EnumWrapper.java index d185950c..21a2464c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/EnumWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/EnumWrapper.java @@ -70,6 +70,17 @@ public class EnumWrapper> { this.getterMethod = getter; } } + + if (!hasEnumValueAnnotation) { + Method enumValueMethod = ClassUtil.getFirstMethod(enumClass, method -> method.getAnnotation(EnumValue.class) != null); + if (enumValueMethod != null) { + String methodName = enumValueMethod.getName(); + if (!(methodName.startsWith("get") && methodName.length() > 3)) { + throw new IllegalStateException("Can not find get method \"" + methodName + "()\" in enum: " + enumClass.getName()); + } + this.getterMethod = enumValueMethod; + } + } }