最近小咸儿在开发项目的时候,写有关插入的一条线时,需要插入到三张表中,所以传过来的是一个组合型的model实体,这个时候就需要很多的set/get的代码,但是经过大牛的指点,发现原来还有BeanUtils.copyProperties这个神器。十分感谢。
BeanUtils.copyProperties提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度。
首先看一下小咸儿项目中封装的代码,这里用到的是重载,根据你传的参数去匹配使用哪个方法,具体的就不多做解释了,因为小咸儿也不是很懂……
// 方法一
public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {
copyProperties(source, target, null, ignoreProperties);
}
// 方法二
private static void copyProperties(Object source, Object target, @Nullable Class editable,
@Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null &&
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
}
根据小咸儿的业务需要,这里就有三个实体是十分相似的,所以使用BeanUtils.copyProperties就会更加的方便。
public IntegralResult integralAnswer(IntegralAnswerModel integralAnswerModel) {
log.info("传入前的IntegralAnswer实体:"+integralAnswerModel);
AnswerEntity answerEntity = new AnswerEntity();
BeanUtils.copyProperties(integralAnswerModel,answerEntity);
answerEntity.setRemark("头脑风暴作答");
answerEntity.setId(IdWorker.nextStringId());
IntegralModel integralModel = new IntegralModel();
String[] ids = new String[]{""};
ids[0] = integralAnswerModel.getUserId();
BeanUtils.copyProperties(integralAnswerModel,integralModel);
integralModel.setPluginId("pluginId_brainstorming");
integralModel.setPrimaryId("pluginId_brainstorming");
integralModel.setReason("作答"+integralAnswerModel.getTheme()+"加分");
integralModel.setTypeKey("answer");
integralModel.setIdInfo(ids);
integralModel.setIntegral(integralAnswerModel.getLikedNumber());
RecordEntity recordEntity = new RecordEntity();
BeanUtils.copyProperties(integralAnswerModel,recordEntity);
recordEntity.setType(1);
recordEntity.setRemark("头脑风暴作答");
recordEntity.setIntegral(integralAnswerModel.getLikedNumber());
recordEntity.setId(IdWorker.nextStringId());
log.info("传入前的integralModel实体:"+integralModel);
IntegralResult addIntegral = integralClientService.addIntegral(integralModel);
if (IntegralResult.SUCCESS.equals(addIntegral.getCode())) {
log.info("传入前的AnswerEntity实体:"+answerEntity);
AnswerEntity result = answerJpa.save(answerEntity);
log.info("插入后的AnswerEntity实体:"+result);
log.info("传入前的RecordEntity实体:" +recordEntity);
RecordEntity recordResult = recordJpa.save(recordEntity);
log.info("插入后的RecordEntity实体:" +recordResult);
if (result==null){
return IntegralResult.build("1111", "头脑风暴作答插入记录失败",result);
} else if (recordResult == null) {
return IntegralResult.build(IntegralResult.FAIL,"头脑风暴作答记录插入失败", recordResult);
}
return IntegralResult.build("0000", "头脑风暴作答加分成功!", addIntegral);
} else {
return IntegralResult.build("1111","头脑风暴调用加分接口失败", addIntegral);
}
}
如果实体还有不一样的字段,但是我还需要该如何是好呢?
这个时候,就能看出来BeanUtils.copyProperties的好处了,如果不一样的字段并且还需要的话,只要自己去set或者get就可以了。可以十分有效的减少代码量。
更多深入的东西,小咸儿也没有研究,期待小咸儿的下一篇博客吧!