/** * Copyright (c) 2011-2020, hubin (jobob@qq.com). * <p> * 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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.baomidou.mybatisplus.toolkit; import com.baomidou.mybatisplus.entity.TableFieldInfo; import com.baomidou.mybatisplus.entity.TableInfo; import com.baomidou.mybatisplus.enums.FieldStrategy; import com.baomidou.mybatisplus.exceptions.MybatisPlusException; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import java.lang.reflect.*; import java.util.*; /** * <p> * 反射工具类 * </p> * * @author Caratacus * @Date 2016-09-22 */ public class ReflectionKit { private static final Log logger = LogFactory.getLog(ReflectionKit.class); /** * <p> * 反射 method 方法名,例如 getId * </p> * * @param field * @param str 属性字符串内容 * @return */ public static String getMethodCapitalize(Field field, final String str) { Class<?> fieldType = field.getType(); // fix #176 return StringUtils.concatCapitalize(boolean.class.equals(fieldType) ? "is" : "get", str); } /** * 获取 public get方法的值 * * @param cls * @param entity 实体 * @param str 属性字符串内容 * @return Object */ public static Object getMethodValue(Class<?> cls, Object entity, String str) { Map<String, Field> fieldMaps = getFieldMap(cls); try { if (MapUtils.isEmpty(fieldMaps)) { throw new MybatisPlusException( String.format("Error: NoSuchField in %s for %s. Cause:", cls.getSimpleName(), str)); } Method method = cls.getMethod(getMethodCapitalize(fieldMaps.get(str), str)); return method.invoke(entity); } catch (NoSuchMethodException e) { throw new MybatisPlusException(String.format("Error: NoSuchMethod in %s. Cause:", cls.getSimpleName()) + e); } catch (IllegalAccessException e) { throw new MybatisPlusException(String.format("Error: Cannot execute a private method. in %s. Cause:", cls.getSimpleName()) + e); } catch (InvocationTargetException e) { throw new MybatisPlusException("Error: InvocationTargetException on getMethodValue. Cause:" + e); } } /** * 获取 public get方法的值 * * @param entity 实体 * @param str 属性字符串内容 * @return Object */ public static Object getMethodValue(Object entity, String str) { if (null == entity) { return null; } return getMethodValue(entity.getClass(), entity, str); } /** * 调用对象的get方法检查对象所有属性是否为null * * @param bean 检查对象 * @return boolean true对象所有属性不为null,false对象所有属性为null */ public static boolean checkFieldValueNotNull(Object bean) { if (null == bean) { return false; } Class<?> cls = bean.getClass(); TableInfo tableInfo = TableInfoHelper.getTableInfo(cls); if (null == tableInfo) { throw new MybatisPlusException(String.format("Error: Could Not find %s in TableInfo Cache. ", cls.getSimpleName())); } boolean result = false; List<TableFieldInfo> fieldList = tableInfo.getFieldList(); for (TableFieldInfo tableFieldInfo : fieldList) { FieldStrategy fieldStrategy = tableFieldInfo.getFieldStrategy(); Object val = getMethodValue(cls, bean, tableFieldInfo.getProperty()); if (FieldStrategy.NOT_EMPTY.equals(fieldStrategy)) { if (StringUtils.checkValNotNull(val)) { result = true; break; } } else { if (null != val) { result = true; break; } } } return result; } /** * 反射对象获取泛型 * * @param clazz 对象 * @param index 泛型所在位置 * @return Class */ @SuppressWarnings("rawtypes") public static Class getSuperClassGenricType(final Class clazz, final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { logger.warn(String.format("Warn: %s's superclass not ParameterizedType", clazz.getSimpleName())); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { logger.warn(String.format("Warn: Index: %s, Size of %s's Parameterized Type: %s .", index, clazz.getSimpleName(), params.length)); return Object.class; } if (!(params[index] instanceof Class)) { logger.warn(String.format("Warn: %s not set the actual class on superclass generic parameter", clazz.getSimpleName())); return Object.class; } return (Class) params[index]; } /** * 获取该类的所有属性列表 * * @param clazz 反射类 * @return */ public static Map<String, Field> getFieldMap(Class<?> clazz) { List<Field> fieldList = getFieldList(clazz); Map<String, Field> fieldMap = Collections.emptyMap(); if (CollectionUtils.isNotEmpty(fieldList)) { fieldMap = new LinkedHashMap<>(); for (Field field : fieldList) { fieldMap.put(field.getName(), field); } } return fieldMap; } /** * 获取该类的所有属性列表 * * @param clazz 反射类 * @return */ public static List<Field> getFieldList(Class<?> clazz) { if (null == clazz) { return null; } List<Field> fieldList = new LinkedList<>(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { /* 过滤静态属性 */ if (Modifier.isStatic(field.getModifiers())) { continue; } /* 过滤 transient关键字修饰的属性 */ if (Modifier.isTransient(field.getModifiers())) { continue; } fieldList.add(field); } /* 处理父类字段 */ Class<?> superClass = clazz.getSuperclass(); if (superClass.equals(Object.class)) { return fieldList; } /* 排除重载属性 */ return excludeOverrideSuperField(fieldList, getFieldList(superClass)); } /** * <p> * 排序重置父类属性 * </p> * * @param fieldList 子类属性 * @param superFieldList 父类属性 */ public static List<Field> excludeOverrideSuperField(List<Field> fieldList, List<Field> superFieldList) { // 子类属性 Map<String, Field> fieldMap = new HashMap<>(); for (Field field : fieldList) { fieldMap.put(field.getName(), field); } for (Field superField : superFieldList) { if (null == fieldMap.get(superField.getName())) { // 加入重置父类属性 fieldList.add(superField); } } return fieldList; } }