NO.73 [bean]Arch4用业务大对象的复制工具类BizVoUtils

--引用涉及的司内工具类 ,恕不提供。

 

    两个简单的Bean:属性基本都是基础类型(如int,float)或一些基础类(如 Date,String),除了名字不一样,属性几乎一模一样,值复制你可以用Apache的BeanUtils.copyProperties,也可以用(司内)SuperBeanTools.simpleCopy。

    如果是复杂Bean(含有以List为形式的下级简单Bean),貌似没有太简单明了的工具,因此,有了这个AR工具BizVoUtils。

 

【例】

PolicyDto

保单大对象

 

EndorseDto

批单大对象

 

有子Dto型属性

PrpCmainDto mainDto

String policyNo;

String applyCode;

...

 

PrpPmain mainDto

String endorDto;

String applyCode;

...

有List型属性(注,List命名一般应完全一致)

List insuredList;

--

List中是PrpCinsuredDto

 

 

List insuredList;

--

List中是PrpPinsuredDto

 

 

 

PrpCinsuredDto中有这些属性

String policyNo;

String insuredCode;

String insuredName;

 

 

PrpPinsuredDto中有这些属性

String policyNo;

String insuredCode;

String insuredName;

...

...

...

 

...

...

 

【例子说明】

  1. 两个业务大对象的属性几乎一模一样——除了子Dto名中或的这一点差异:保单是PrpC,批单是PrpP
  2. List属性命名一致(见过不规范者,比如保单大对象中被保险人List命名成prpCinsuredList,批单大对象中命名成prpPinsuredList,也可以改工具中代码以解决,但很麻烦,暂不提供支持,所以没啥事,还是都照规范来吧);

 

【使用说明】

  1. 由于Arch4中底层Dto无基础类型(double,int),只有基础类(Double,Integer),因此本版不支持基础类型;
  2. 字段名除了差异部分,其它字母应完全一致,大小写也要完全一致。如果有某个字段赋值未成功,请检查是否符合这个条件;
  3. 实现公共特殊字段的赋值——比如批单大对象中EndorNo是公共的,但保单大对象中却没有,因此,在从保单大对象向批单大对象赋值时,若没有这个功能,还是得对每个子对象拿出来去单独赋值EndorNo;
  4. 如果目标Dto中已经有部分值,此工具实现了不覆盖,先不多解释。

 

【使用样例】

两个不同业务大对象的拷贝

//比如从保单Dto要生成批单Dto
//prpCmainDto是一个已经从数据库或页面组装好的大对象
//先创建目录对象prpPmainDto
Map<String, Object> specialFieldMap = new HashMap<String, Object>();
specialFieldMap.put("EndorNo", endorNo);//字段名首字母要大写
PrpPmainDto prpPmainDto = new PrpPmainDto();
BizVoUtils.copyBizObj(prpCmainDto, prpPmainDto ,
		BizVoUtils.POLICY, BizVoUtils.ENDOR,
		specialFieldMap);

业务大对象自己的深拷贝

   PrpCmainDto prpCmainDto2 = new PrpCmainDto();
   BizDtoUtil.copyBizObj(prpCmainDto,prpCmainDto2);


【源码】 

package com.sinosoft.utility.bean;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.sinosoft.sysframework.common.util.ObjectUtils;

/**
 * 前身BizDtoUtil
 * 
 * @author amosryan 2010-08
 * 
 */
public class BizVoUtils extends DtoUtils {

	/** 是否打印调试信息? */
	private static boolean verbose = true;

	/** 项目 */
	public static final String PROJECT = "PrpSproject";

	/** 项目批改 */
	public static final String ENDOR_PROJECT = "PrpSprojectEndor";

	/** 保单 */
	public static final String POLICY = "PrpC";

	/** 批单 */
	public static final String ENDOR = "PrpP";

	/** 可直接赋值的类属性类型 */
	private static Map<Class, String> supportTypeMap = new HashMap<Class, String>();
	static {
		supportTypeMap.put(Integer.class, "");
		supportTypeMap.put(Long.class, "");
		supportTypeMap.put(Double.class, "");
		supportTypeMap.put(BigDecimal.class, "");
		supportTypeMap.put(String.class, "");
		supportTypeMap.put(Short.class, "");
		supportTypeMap.put(Date.class, "");
		supportTypeMap.put(java.sql.Date.class, "");
		supportTypeMap.put(Boolean.class, "");
		supportTypeMap.put(byte[].class, "");
	}

	/**
	 * 用于大对象自己深拷贝
	 * @param target 目标业务Dto
	 * @param source 源业务Dto
	 * @param targetBizType 目标业务Dto业务类型
	 * @param sourceBizType 源业务Dto业务类型
	 */
	public static void copyBizObj(Object source, Object target) {
		  return copyBizObj(source,target,"","",null);
	}

	/**
	 * 复制复杂的业务大对象(目标对象某属性有值则跳过)
	 * 
	 * @param source
	 * @param target
	 * @param sourceBizType
	 * @param targetBizType
	 * @param specialFieldsMap
	 *            需要给target传值的特殊域,常用于target比source多出的主键,传格式以map.put("fieldName",fieldValue
	 *            )传值 (注意FieldName首字母大写)
	 */
	public static void copyBizObj(Object source, Object target,
			String sourceBizType, String targetBizType,
			Map<String, Object> specialFieldsMap) {
		List targetSetMethodList = ObjectUtils.getSetter(target.getClass());
		List sourceGetMethodList = ObjectUtils.getGetter(source.getClass());
		Map sourceGetMethodMap = new HashMap();
		if (specialFieldsMap == null) {
			specialFieldsMap = new HashMap();
		}
		for (Iterator i = sourceGetMethodList.iterator(); i.hasNext();) {
			Method sourceGetMethod = (Method) i.next();
			sourceGetMethodMap.put(sourceGetMethod.getName(), sourceGetMethod);
		}
		try {
			for (Iterator i = targetSetMethodList.iterator(); i.hasNext();) {
				Method targetSetMethod = (Method) i.next();
				String targetFieldName = targetSetMethod.getName().substring(3);
				String sourceFieldName = targetFieldName.replaceFirst(
						targetBizType, sourceBizType);
				// 如果是List型,则根据源创建目标Dto,放入目标List
				Method sourceGetMethod = (Method) sourceGetMethodMap.get("get"
						+ sourceFieldName);
				if (sourceGetMethod != null) {
					Object sourceValue = sourceGetMethod.invoke(source,
							new Object[0]);
					if (sourceValue != null) {
						String sourceName = getBeanName(sourceValue);
						String targetName = null;
						if (sourceValue instanceof List) {// List情况
							List targetList = (List) DtoUtils.getFieldValue(
									target, targetFieldName);
							if (targetList == null) {// 如果原来无值,新建List
								targetList = new ArrayList();
								targetSetMethod.invoke(target,
										new Object[] { targetList });
							}
							List sourceList = (List) sourceValue;
							for (int j = 0; j < sourceList.size(); j++) {
								Object o = sourceList.get(j);
								Object obj = null;
								if (j < targetList.size()) {// 如果List此位置有值
									obj = targetList.get(j);
									copyBizObj(o, obj, sourceBizType,
											targetBizType, specialFieldsMap);
								} else {// 此位置无值就新建
									String packageName = getPackageName(o);
									String sourceBeanName = getBeanName(o);
									targetName = packageName
											+ sourceBeanName.replaceFirst(
													sourceBizType,
													targetBizType);
									obj = getInstance(targetName, packageName,
											sourceBeanName);
									copyBizObj(o, obj, sourceBizType,
											targetBizType, specialFieldsMap);
									targetList.add(obj);
								}
							}
							targetName = ArrayList.class.getName();
						} else if (!supportTypeMap.containsKey(sourceValue
								.getClass())) {// 业务对象情况
							Object obj = DtoUtils.getFieldValue(target,
									targetFieldName);
							if (obj == null) {
								String packageName = getPackageName(sourceValue);
								targetName = packageName
										+ sourceName.replaceFirst(
												sourceBizType, targetBizType);
								if (verbose) {
									System.out.println();
									System.out.println(" In unsupport:---");
									System.out.println(" packageName:"
											+ packageName);
									System.out.println(" targetName:"
											+ targetName);
								}
								obj = getInstance(targetName, packageName,
										sourceName);
								targetSetMethod.invoke(target,
										new Object[] { obj });
							}
							copyBizObj(sourceValue, obj, sourceBizType,
									targetBizType, specialFieldsMap);
						} else {//叶子属性进行值拷贝
							targetName = sourceValue.getClass().getName();
							Object obj = DtoUtils.getFieldValue(target,
									targetFieldName);
							if (obj == null) {
								targetSetMethod.invoke(target,
										new Object[] { sourceValue });
							}
						}
						if (verbose) {
							System.out.println();
							System.out.println("Source名称:" + sourceFieldName);
							System.out.println("Source类型:"
									+ sourceValue.getClass());
							System.out.println("target名称:" + targetFieldName);
							System.out.println("target类型:" + targetName);
						}
					}
				} else if (specialFieldsMap.containsKey(sourceFieldName)) {
					targetSetMethod.invoke(target,
							new Object[] { specialFieldsMap
									.get(sourceFieldName) });
					if (verbose) {
						System.out.println();
						System.out.println(sourceFieldName
								+ " exists in SpecialFieldMap!");
					}
				} else {
					if (verbose) {
						System.out.println();
						System.out.println(sourceFieldName
								+ " not exists in source!");
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static Object getInstance(String targetName, String packageName,
			String sourceName) throws Exception {
		Object obj = getInstance(targetName);
		if (obj == null) {
			targetName = packageName + sourceName;
			obj = getInstance(targetName);
		}
		return obj;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值