--引用涉及的司内工具类 ,恕不提供。
两个简单的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; |
... |
... |
... |
|
... |
... |
【例子说明】
- 两个业务大对象的属性几乎一模一样——除了子Dto名中或的这一点差异:保单是PrpC,批单是PrpP;
- List属性命名一致(见过不规范者,比如保单大对象中被保险人List命名成prpCinsuredList,批单大对象中命名成prpPinsuredList,也可以改工具中代码以解决,但很麻烦,暂不提供支持,所以没啥事,还是都照规范来吧);
【使用说明】
- 由于Arch4中底层Dto无基础类型(double,int),只有基础类(Double,Integer),因此本版不支持基础类型;
- 字段名除了差异部分,其它字母应完全一致,大小写也要完全一致。如果有某个字段赋值未成功,请检查是否符合这个条件;
- 实现公共特殊字段的赋值——比如批单大对象中EndorNo是公共的,但保单大对象中却没有,因此,在从保单大对象向批单大对象赋值时,若没有这个功能,还是得对每个子对象拿出来去单独赋值EndorNo;
- 如果目标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;
}
}