Press "Enter" to skip to content

对视图模型构造相关参数的轮子

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

清明放假没事在家写一些常用的轮子,以便减少一些重复繁琐的编码工作。

 

话不多说,继续往下看

 

有时我们的接口数据返回给前端或者导出为excel时,需要给相关值带单位(kg/立方米/%等)、或保留小数位等。尤其是一些统计类的报表,值特别多、单位也就贼多了。

 

做法

 

 

    1. 查询时在sql中拼接。给sql添加了好多无聊的字符,看起来都不好看,维护性不好,看起来都头疼

 

    1. 业务代码中循环拼接。这也很麻烦

 

    1. 交给前端回显时去拼接。前端有可能要骂娘

 

 

 

 

    1. 既然是面向对象编程,那最好就是有维护一个视图对象,供我们返回到前端

 

    1. 一般我们通过sql查出来的po、dto模型或者通过业务处理后的bo模型不会直接给到前端,而是处理到vo再给到前端。

 

    1. 所以我就在想,我可以定义一些注解指明这个属性的单位是啥、保留小数位、或者替换符,然后通过一个对象转换的方法,获取到该属性注解的值,再通过反射赋予到vo模型中去。

 

    1. 想起来很简单,说干就干。不到两小时就撸出来了这个轮子,代码都很简单,主要是要有一些可以简化撸码的想法。也方便我们工作。

 

 

代码

 

可置于需要注解的对象的属性

 

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RespVoProperty {
	
	int keepDecimal() default -1;
	
	String unit() default "";
	
	String replaceStr() default "";
}

 

vo模型使用示例

 

@Data
public class PersonVo {
    private String name;
    @RespVoProperty(unit = "块")
    private String money;
    @RespVoProperty(unit = "岁", replaceStr = "-")
    private String age;
    @RespVoProperty(unit = "kg", keepDecimal = 2)
    private String weight;
}

 

转换方法

 

public class Converts {
	
	
	private static <T> void formatVoField(Object source, int keepDecimal, String unit, String replaceStr, T data, Field field) {
		if (Objects.equals("serialVersionUID", field.getName())) {
			return;
		}
		Object oldTemp = null;
		try {
			oldTemp = ReflectionUtil.invokeGetterMethod(source, field.getName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		switch (field.getType().getSimpleName()) {
			case "Float":
				if (ObjectUtil.isNotNull(oldTemp)) {
					if (keepDecimal == -1) {
						oldTemp = new BigDecimal((float) oldTemp);
					} else {
						oldTemp = new BigDecimal((float) oldTemp)
								.setScale(keepDecimal, BigDecimal.ROUND_HALF_UP);
					}
					oldTemp = String.valueOf(oldTemp).concat(unit);
				} else {
					oldTemp = replaceStr;
				}
				break;
			case "Integer":
				if (ObjectUtil.isNotNull(oldTemp)) {
					oldTemp = String.valueOf(oldTemp).concat(unit);
				} else {
					oldTemp = replaceStr;
				}
				break;
			case "BigDecimal":
				if (ObjectUtil.isNotNull(oldTemp)) {
					if (keepDecimal == -1) {
						oldTemp = new BigDecimal(oldTemp.toString());
					} else {
						oldTemp = new BigDecimal(oldTemp.toString())
								.setScale(keepDecimal, BigDecimal.ROUND_HALF_UP);
					}
					oldTemp = String.valueOf(oldTemp).concat(unit);
				} else {
					oldTemp = replaceStr;
				}
				break;
			default:
		}
		if (ObjectUtil.isNotNull(oldTemp)) {
			ReflectionUtil.invokeSetterMethod(data, field.getName(), oldTemp);
		}
	}

	
	public static <T> T toRespVo(Object source, final Class<T> voClass) {
		T data = null;
		try {
			data = voClass.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}

		Map<String, Field> voFieldsMap = Arrays.stream(voClass.getDeclaredFields())
				.collect(Collectors.toMap(Field::getName, Function.identity()));

		for (Field field : source.getClass().getDeclaredFields()) {
			RespVoProperty property = Optional.ofNullable(voFieldsMap.get(field.getName()))
					.map(annotationClass -> annotationClass.getAnnotation(RespVoProperty.class))
					.orElse(null);
			if (Objects.isNull(property)) {
				formatVoField(source, -1, "", "", data, field);
			} else {
				formatVoField(source, property.keepDecimal(), property.unit(), property.replaceStr(), data, field);
			}
		}
		return data;
	}

	
	public static <T> List<T> toRespVos(List<? extends Object> sources, final Class<T> voClass) {
		List<T> targets = new ArrayList<>();
		if (CollectionUtils.isEmpty(sources)) {
			return targets;
		}
		sources.parallelStream().forEach(source -> targets.add(toRespVo(source, voClass)));
		return targets;
	}


	public static void main(String[] args) {
		List<Person> list = new ArrayList<>();
		Person data1 = new Person();
		data1.setName("李三");
		data1.setAge(14);
		data1.setMoney(BigDecimal.ONE);
		data1.setWeight(15.2f);
		System.out.println("-----------------单对象转化vo----------------");
		System.out.println(toRespVo(data1, PersonVo.class));
		System.out.println("--------------------------------------------");

		System.out.println("-----------------集合对象转化vo----------------");
		list.add(data1);
		Person data2 = new Person();
		data2.setName("wangwu");
		data2.setAge(45);
		data2.setMoney(BigDecimal.valueOf(6.41f));
		data2.setWeight(null);
		list.add(data2);
		Person data3 = new Person();
		data3.setName("张思");
		data3.setAge(null);
		data3.setMoney(BigDecimal.valueOf(25f));
		data3.setWeight(17.689f);
		list.add(data3);
		System.out.println(toRespVos(list, PersonVo.class));
	}
}

 

方法中用到了一个反射方法工具

 

ReflectionUtil工具地址

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注