【Java】使用BeanUtils的copyProperties含过滤属性参数(ignoreProperties)方法的应用

问题

需求:
来源于更新数据的一个接口,要求可以修改类中某一些字段的值,可以仅修改一部分,没有修改的字段默认为不修改。

例中使用了一个视图层的包装对象vo,包含了需要更新的目标底层实体po的一个扩展子类(假设这个对象就是poi),和一些其他的无关属性。从前端获取到已经改好数据的vo后,需要保存已经更新的po。


思路

使用BeanUtils.copyProperties(source, target, ignoreProperties)这个方法,将源的属性,过滤掉一部分属性名,复制到目标上

ignoreProperties的声明类型是String… ignoreProperties

为获取一个能得到属性字段名的数组,需要用反射机制

过程

  1. 新建一个po对象,使用copyProperties复制poi已有值的属性到po里
  2. 设计一个方法获取不为空的字段名数组,供过滤功能的调用
  3. 再使用copyProperties的过滤重载方法,将原po复制到新po

反射获取字段名的实现

目标是获取不为空的字段

/**
 * 用反射机制来得到vo中itemsCustom的不为空的属性
 * @param objClass 为目标的Class对象,调用时为实体类的Class对象,并不是vo
 * @param vo
 * @return
 * @throws ClassNotFoundException 
 */
private String[] getProperties(Class objClass,ItemsQueryVo vo) throws ClassNotFoundException {
	//得到ItemsCustom的class类
	ItemsCustom obj = vo.getItemsCustom();
	List<String> properties = new ArrayList<>();
	//遍历字段
	try {
		//使用getDeclaredFields()方法而不是getFields()的原因是
		//该方法明确的只需要匹配objClass类的字段,
		//不使用obj.getClass()的原因也是如此,因为obj的类继承自objClass的类
		for(Field field: objClass.getDeclaredFields()) {
			//使其可以访问private
			field.setAccessible(true);
			//如果字段不为空
			if(field.get(obj)!=null)
				properties.add(field.getName());
		}
	}catch (Exception e) {
		/*
		 * 如果获取出了错,return null的方法相当于
		 * 源的所有字段都是空的,目标在外部会被完全覆盖掉,这次更新相当于无效了
		 */
		return null;
	}
	//转数组
	String[] propers = new String[properties.size()];
	return properties.toArray(propers);
}

上段代码就实现了过程中的第二步

利用上述代码的简单方法可以写更多类似且更有通用性的工具

你可能感兴趣的:(后端,Java)