diff --git a/README.ZH_CN.md b/README.ZH_CN.md index b6320ec..b2506cc 100644 --- a/README.ZH_CN.md +++ b/README.ZH_CN.md @@ -20,14 +20,14 @@ $ mvn clean install io.leego mypages - 1.0.0 + 1.0.1 ``` ### Gradle ```xml -implementation 'io.leego:mypages:1.0.0' +implementation 'io.leego:mypages:1.0.1' ``` ## 数据库 diff --git a/README.md b/README.md index d6d91c0..106524b 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,14 @@ $ mvn clean install io.leego mypages - 1.0.0 + 1.0.1 ``` ### Gradle ```xml -implementation 'io.leego:mypages:1.0.0' +implementation 'io.leego:mypages:1.0.1' ``` ## Supported diff --git a/docs/STARTER_USERGUIDE.ZH_CN.md b/docs/STARTER_USERGUIDE.ZH_CN.md index 177983a..ece25fa 100644 --- a/docs/STARTER_USERGUIDE.ZH_CN.md +++ b/docs/STARTER_USERGUIDE.ZH_CN.md @@ -14,14 +14,14 @@ MyPages是Java实现基于[MyBatis](https://github.com/mybatis/mybatis-3)的开 io.leego mypages-spring-boot-starter - 1.0.0 + 1.0.1 ``` ## 3.2 Gradle ```xml -implementation 'io.leego:mypages-spring-boot-starter:1.0.0' +implementation 'io.leego:mypages-spring-boot-starter:1.0.1' ``` # 4. 配置 diff --git a/docs/STARTER_USERGUIDE.md b/docs/STARTER_USERGUIDE.md index e2a3118..d715018 100644 --- a/docs/STARTER_USERGUIDE.md +++ b/docs/STARTER_USERGUIDE.md @@ -14,14 +14,14 @@ Please make sure the Java version is 1.8 and above. io.leego mypages-spring-boot-starter - 1.0.0 + 1.0.1 ``` ## 3.2 Gradle ```xml -implementation 'io.leego:mypages-spring-boot-starter:1.0.0' +implementation 'io.leego:mypages-spring-boot-starter:1.0.1' ``` # 4. Configuration diff --git a/docs/USERGUIDE.ZH_CN.md b/docs/USERGUIDE.ZH_CN.md index e576765..b238950 100644 --- a/docs/USERGUIDE.ZH_CN.md +++ b/docs/USERGUIDE.ZH_CN.md @@ -14,14 +14,14 @@ MyPages是Java实现基于[MyBatis](https://github.com/mybatis/mybatis-3)的开 io.leego mypages - 1.0.0 + 1.0.1 ``` ## 3.2 Gradle ```xml -implementation 'io.leego:mypages:1.0.0' +implementation 'io.leego:mypages:1.0.1' ``` # 4. 快速设置 diff --git a/docs/USERGUIDE.md b/docs/USERGUIDE.md index 27a5fee..a7c0744 100644 --- a/docs/USERGUIDE.md +++ b/docs/USERGUIDE.md @@ -14,14 +14,14 @@ Please make sure the Java version is 1.8 and above. io.leego mypages - 1.0.0 + 1.0.1 ``` ## 3.2 Gradle ```xml -implementation 'io.leego:mypages:1.0.0' +implementation 'io.leego:mypages:1.0.1' ``` # 4. Quick Setup diff --git a/mypages-spring-boot-starter/pom.xml b/mypages-spring-boot-starter/pom.xml index 72d5fe7..2aabe1e 100644 --- a/mypages-spring-boot-starter/pom.xml +++ b/mypages-spring-boot-starter/pom.xml @@ -9,7 +9,7 @@ io.leego mypages-parent - 1.0.0 + 1.0.1 mypages-spring-boot-starter diff --git a/mypages/pom.xml b/mypages/pom.xml index f70e1e6..d285d01 100644 --- a/mypages/pom.xml +++ b/mypages/pom.xml @@ -9,7 +9,7 @@ io.leego mypages-parent - 1.0.0 + 1.0.1 mypages diff --git a/mypages/src/main/java/io/leego/mypages/dialect/AbstractDialect.java b/mypages/src/main/java/io/leego/mypages/dialect/AbstractDialect.java index d3f1b1b..57a8f21 100644 --- a/mypages/src/main/java/io/leego/mypages/dialect/AbstractDialect.java +++ b/mypages/src/main/java/io/leego/mypages/dialect/AbstractDialect.java @@ -62,7 +62,7 @@ public Object assembleParameter(MappedStatement ms, Object parameter, BoundSql b paramMap = new HashMap<>((Map) parameter); } else { boolean hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameter.getClass()); - paramMap = hasTypeHandler ? new HashMap<>() : BeanUtils.readAll(parameter); + paramMap = hasTypeHandler ? new HashMap<>() : BeanUtils.readAll(parameter, HashMap::new, k -> k, v -> v); } List parameterMappings; if (boundSql.getParameterMappings() == null) { diff --git a/mypages/src/main/java/io/leego/mypages/util/BeanUtils.java b/mypages/src/main/java/io/leego/mypages/util/BeanUtils.java index 026f313..f061265 100644 --- a/mypages/src/main/java/io/leego/mypages/util/BeanUtils.java +++ b/mypages/src/main/java/io/leego/mypages/util/BeanUtils.java @@ -9,6 +9,7 @@ import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import java.util.function.Supplier; /** @@ -23,152 +24,167 @@ private BeanUtils() { } /** - * Returns read method name. + * Returns read-method name. *

Example:

-     * String s = getReadMethodName("name"); // getName
+     * String methodName = getReadMethodName("name"); // The method name is "getName".
      * 
- * @param fieldName The name of the property - * @return read method name + * @param fieldName The name of the property. + * @return read-method name. */ public static String getReadMethodName(String fieldName) { - return GET_PREFIX + upperCaseFirst(fieldName); + return buildMethodName(GET_PREFIX, fieldName); } /** - * Returns read method name. + * Returns read-method name. *

Example 1:

-     * String s = getReadMethodName("name", false); // getName
+     * String methodName = getReadMethodName("name", false); // The method name is "getName".
      * 
*

Example 2:

-     * String s = getReadMethodName("success", true); // isSuccess
+     * String methodName = getReadMethodName("success", true); // The method name is "isSuccess".
      * 
- * @param fieldName The name of the property - * @param primitiveBoolean Whether the field type is primitive boolean - * @return read method name + * @param fieldName The name of the property. + * @param primitiveBoolean Whether the field type is primitive boolean. + * @return read-method name. */ public static String getReadMethodName(String fieldName, boolean primitiveBoolean) { - return (primitiveBoolean ? IS_PREFIX : GET_PREFIX) + upperCaseFirst(fieldName); + return buildMethodName((primitiveBoolean ? IS_PREFIX : GET_PREFIX), fieldName); } /** - * Returns read method name. + * Returns read-method name. + *

Example:

+     * String methodName = getPrimitiveBooleanReadMethodName("success"); // The method name is "isSuccess".
+     * 
+ * @param fieldName The name of the property. + * @return read-method name. + */ + public static String getPrimitiveBooleanReadMethodName(String fieldName) { + return buildMethodName(IS_PREFIX, fieldName); + } + + /** + * Returns read-method name. *

Example 1:

-     * Field field = Foo.class.getField("name"); // field.getType() != boolean.class
-     * String s = getReadMethodName(field); // getName
+     * Field field = Foo.class.getDeclaredField("name"); // Assume that the field type is not boolean.
+     * String methodName = getReadMethodName(field); // The method name is "getName".
      * 
*

Example 2:

-     * Field field = Foo.class.getField("success"); // field.getType() == boolean.class
-     * String s = getReadMethodName(field); // isSuccess
+     * Field field = Foo.class.getDeclaredField("success"); // Assume that the field type is boolean.
+     * String methodName = getReadMethodName(field); // The method name is "isSuccess".
      * 
* @param field {@link Field} - * @return read method name + * @return read-method name. */ public static String getReadMethodName(Field field) { return getReadMethodName(field.getName(), field.getType() == boolean.class); } /** - * Returns read method name. + * Returns read-method name. *

Example 1:

-     * Field field = Foo.class.getField("name");
-     * String s = getReadMethodName(field, false); // getName
+     * Field field = Foo.class.getDeclaredField("name"); // Assume that the field type is not boolean./code>
+     * String methodName = getReadMethodName(field, false); // The method name is "getName".
      * 
*

Example 2:

-     * Field field = Foo.class.getField("success");
-     * String s = getReadMethodName(field, true); // isSuccess
+     * Field field = Foo.class.getDeclaredField("success"); // Assume that the field type is boolean.
+     * String methodName = getReadMethodName(field, true); // The method name is "isSuccess".
      * 
* @param field {@link Field} - * @param primitiveBoolean Whether the field type is primitive boolean - * @return read method name + * @param primitiveBoolean Whether the field type is primitive boolean. + * @return read-method name. */ public static String getReadMethodName(Field field, boolean primitiveBoolean) { return getReadMethodName(field.getName(), primitiveBoolean); } /** - * Returns write method name. + * Returns write-method name. *

Example:

-     * String s = getWriteMethodName("name"); // setName
+     * String methodName = getWriteMethodName("name"); // The method name is "setName".
      * 
- * @param fieldName The name of the property - * @return write method name + * @param fieldName The name of the property. + * @return write-method name. */ public static String getWriteMethodName(String fieldName) { - return SET_PREFIX + upperCaseFirst(fieldName); + return buildMethodName(SET_PREFIX, fieldName); } /** - * Returns write method name. + * Returns write-method name. *

Example:

-     * Field field = Foo.class.getField("name");
-     * String s = getWriteMethodName(field); // setName
+     * Field field = Foo.class.getDeclaredField("name");
+     * String methodName = getWriteMethodName(field); // The method name is "setName".
      * 
* @param field {@link Field} - * @return write method name + * @return write-method name. */ public static String getWriteMethodName(Field field) { - return SET_PREFIX + upperCaseFirst(field.getName()); + return buildMethodName(SET_PREFIX, field.getName()); } - /** - * Returns read method. + * Returns read-method. *

Example:

-     * Method m = getReadMethod(Foo.class, "name");
+     * Method method = getReadMethod(Foo.class, "name");
      * 
- * @param type The Class object for the target bean - * @param fieldName The name of the property - * @return read method + * @param type The Class object for the target bean. + * @param fieldName The name of the property. + * @return read-method + * @throws IntrospectionException if an exception occurs during introspection. */ public static Method getReadMethod(Class type, String fieldName) throws IntrospectionException { return getPropertyDescriptor(fieldName, type).getReadMethod(); } /** - * Returns read method. + * Returns read-method. *

Example:

-     * Field field = Foo.class.getField("name");
-     * Method m = getReadMethod(field);
+     * Field field = Foo.class.getDeclaredField("name");
+     * Method method = getReadMethod(field);
      * 
* @param field {@link Field} - * @return read method + * @return read-method + * @throws IntrospectionException if an exception occurs during introspection. */ public static Method getReadMethod(Field field) throws IntrospectionException { return getReadMethod(field.getDeclaringClass(), field.getName()); } /** - * Returns write method. + * Returns write-method. *

Example:

-     * String s = getWriteMethod(Foo.class, "name");
+     * String methodName = getWriteMethod(Foo.class, "name");
      * 
* @param type The Class object for the target bean * @param fieldName The name of the property - * @return write method + * @return write-method + * @throws IntrospectionException if an exception occurs during introspection. */ public static Method getWriteMethod(Class type, String fieldName) throws IntrospectionException { return getPropertyDescriptor(fieldName, type).getWriteMethod(); } /** - * Returns write method. + * Returns write-method. *

Example:

-     * Field field = Foo.class.getField("name");
-     * Method m = getWriteMethod(field);
+     * Field field = Foo.class.getDeclaredField("name");
+     * Method method = getWriteMethod(field);
      * 
* @param field {@link Field} - * @return read method + * @return read-method + * @throws IntrospectionException if an exception occurs during introspection. */ public static Method getWriteMethod(Field field) throws IntrospectionException { return getWriteMethod(field.getDeclaringClass(), field.getName()); } - /** * Returns value of the field of the object. * @param o Target bean * @param fieldName The name of the property * @return value + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -189,6 +205,7 @@ public static Object read(Object o, String fieldName) throws IntrospectionExcept * @param o Target bean * @param field {@link Field} * @return value + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -225,6 +242,7 @@ public static Object read(Object o, Method method) throws IllegalAccessException * @param fieldName The name of the property * @param returnType The return type * @return value + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -243,6 +261,7 @@ public static T read(Object o, String fieldName, Class returnType) throws * @param field {@link Field} * @param returnType The return type * @return value + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -280,7 +299,7 @@ public static T read(Object o, Method method, Class returnType) throws Il * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. */ - public static Map readAll(Object o) throws IntrospectionException, IllegalAccessException, InvocationTargetException { + public static Map readAll(Object o) throws IntrospectionException, IllegalAccessException, InvocationTargetException { return readAll(o, HashMap::new); } @@ -293,9 +312,9 @@ public static Map readAll(Object o) throws IntrospectionExceptio * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. */ - public static Map readAll(Object o, Supplier> mapFactory) throws IllegalAccessException, InvocationTargetException, IntrospectionException { + public static Map readAll(Object o, Supplier> mapFactory) throws IllegalAccessException, InvocationTargetException, IntrospectionException { PropertyDescriptor[] descriptors = getPropertyDescriptors(o.getClass()); - Map map = mapFactory.get(); + Map map = mapFactory.get(); for (PropertyDescriptor descriptor : descriptors) { map.put(descriptor.getName(), read(o, descriptor.getReadMethod())); } @@ -303,11 +322,57 @@ public static Map readAll(Object o, Supplier } /** - * Invokes the underlying method represented by field name + * Returns values of all fields of the object. + * @param o Target bean + * @param mapFactory The map factory + * @param keyMapper The mapping function to produce keys + * @param valueMapper The mapping function to produce values + * @return values + * @throws IntrospectionException if an exception occurs during introspection. + * @throws IllegalAccessException if the method is not accessible. + * @throws InvocationTargetException if the underlying method throws an exception. + */ + public static Map readAll(Object o, Supplier> mapFactory, Function keyMapper, Function valueMapper) throws IllegalAccessException, InvocationTargetException, IntrospectionException { + PropertyDescriptor[] descriptors = getPropertyDescriptors(o.getClass()); + Map map = mapFactory.get(); + for (PropertyDescriptor descriptor : descriptors) { + String key = descriptor.getName(); + Object value = read(o, descriptor.getReadMethod()); + if (key != null && value != null) { + map.put(keyMapper.apply(key), valueMapper.apply(value)); + } + } + return map; + } + + /** + * Returns an object of the specified type by a map。 + * @param map The map + * @param beanFactory The bean factory + * @return object + */ + public static T fromMap(Map map, Supplier beanFactory) { + T bean = beanFactory.get(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() == null || entry.getValue() == null) { + continue; + } + try { + write(bean, String.valueOf(entry.getKey()), entry.getValue()); + } catch (Exception ignored) { + // ignored + } + } + return bean; + } + + /** + * Invokes the underlying method represented by field name. * @param o Target bean * @param fieldName The name of the property * @param arg The argument used for the method call * @return result + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -324,11 +389,12 @@ public static Object write(Object o, String fieldName, Object arg) throws Intros } /** - * Invokes the underlying method represented by field + * Invokes the underlying method represented by field. * @param o Target bean * @param field {@link Field} * @param arg The argument used for the method call * @return result + * @throws IntrospectionException if an exception occurs during introspection. * @throws NoSuchMethodException if method is not found. * @throws IllegalAccessException if the method is not accessible. * @throws InvocationTargetException if the underlying method throws an exception. @@ -360,7 +426,6 @@ public static Object write(Object o, Method method, Object arg) throws IllegalAc return method.invoke(o, arg); } - /** * Returns a {@link PropertyDescriptor} for a property that follows * the standard Java convention. @@ -407,15 +472,17 @@ public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass) th return Introspector.getBeanInfo(beanClass).getPropertyDescriptors(); } - /** * Returns a {@link String} which capitalizes the first letter of the string. */ - private static String upperCaseFirst(String s) { - if (s != null && s.length() > 0) { - return s.substring(0, 1).toUpperCase() + s.substring(1); + private static String buildMethodName(String prefix, String s) { + if (s == null || s.length() == 0) { + return null; + } + if (Character.isUpperCase(s.charAt(0)) || s.length() > 1 && Character.isUpperCase(s.charAt(1))) { + return prefix + s; } - return s; + return prefix + s.substring(0, 1).toUpperCase() + s.substring(1); } } diff --git a/pom.xml b/pom.xml index 40c777b..ed33d03 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ io.leego mypages-parent - 1.0.0 + 1.0.1 pom ${project.artifactId} MyPages is a java based, open source pagination plugin for MyBatis that simplifies database paging queries.