利用Java反射机制将Map集合转成实体类

时间:2025-02-16 10:43:04

当有需要将Map的字段一一赋值到实体类时,发现一个一个字段取值和赋值操作比较繁琐,如果Map中数据类型不一致,还需要做类型强转。所以通过反射自动把Map的数据转成实体类中,可以让业务代码更加美观。

public static <T> T mapToEntity(Map<?, ?> map, Class<T> clazz) {
		// 验证Map和实体类Class对象是否为空
		(map, "map cannot be null");
		(clazz, "entity class cannot be null");
		try {
			List<Field> allFields = new ArrayList<>();
			T t = ();
			Class<?> aClass = clazz;
			do {
				// 利用Java反射获取自身属性以及父类属性
				((()).collect(()));
				aClass = ();
				// Object类为超级大类,到了Object类,继承关系已到了顶点,不需要处理了
			} while (!((), ()));
			// 对实体类的属性进行遍历
			for (Field field : allFields) {
				// 获取属性名称
				String fieldName = ();
				// 属性对应的实体类名称,这里需要一一对应,否则取不到值
				Object data = (fieldName);
				// 按照Java约定的getter、setter方法命名规范,拼装setter方法名
				String methodName = ("set{}{}", (0, 1).toUpperCase(), (1));
				// 获取setter方法的Method对象
				Method method = (methodName, ());
				// 利用Java反射调用实体对象的setter方法对属性进行赋值操作
				(t, getData(data, ()));
			}
			return t;
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (NoSuchMethodException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 这里的这个方法是为了兼容Sql语句查询后返回的Map。
	 * 在使用Mybatis查询后返回的数据类型为了兼容都使用了大类型,本来是int类型的数据
	 * 但还是返回了long类型,在这里就做了特殊处理,如果实体类中属性为int,Map中类型为Long时,
	 * 就对类型进行转换。在这里还可以做其他的兼容处理
	 */
	private static Object getData(Object data, Class<?> type) {
		String typeName = ();
		if ((typeName, ())) {
			if (data instanceof Long) {
				return ((Long) data).intValue();
			}
		}
		return data;
	}