分享一个方法,适用于更新时的实体重构。
当更新时Domain中属性太多,不想把所有的属性都拼接到update中,那么就用这个方法吧~
方法中执行了遍历属性与其值,确认哪些属性的值需要更新,返回需要更新的属性与值。
这样update语句就可以相对精简许多,但update前的select避免不了了( ̄▽ ̄)",就在校验时间戳的时候查出来捎带上吧。
话不多说,上代码:
/**
* 编辑rebuild <br/>
* 说明:遍历入参所有属性,对比变化的值进行更新,没变化的不更新 <br/>
* 1.infoDomain为前面传入参数(其中包含未变化值的参数)<br/>
* 2.queryDomain为查询数据库数据(作为基准与infoDomain对比,确定哪些数据是变化了的)<br/>
* 3.c指定的T类型class,用于反射实例化。<br/>
* 4.返回值T,对比后的结果,只存储变化的值,用于后续更新
*
* @author Jintao.Wang
*/
public <T> T rebuildEditInfo(T infoDomain, T queryDomain, Class<T> c) throws Exception {
// 获取入参属性的List
List<Field> infolist = Arrays.asList(infoDomain.getClass().getDeclaredFields());
List<Field> querydtolist = Arrays.asList(queryDomain.getClass().getDeclaredFields());
// 构建入参map<属性名,Field>
Map<String, Field> infoMap = infolist.stream().collect(Collectors.toMap(Field::getName, p -> p));
Map<String, Field> querydtoMap = querydtolist.stream().collect(Collectors.toMap(Field::getName, p -> p));
List<String> propNameList = new ArrayList<>();
for (Field f : infolist) {
// 获取属性的类型
if (Objects.equals(f.getName(), "serialVersionUID")) {
continue;
}
f.setAccessible(true);
Field k = querydtoMap.get(f.getName());
k.setAccessible(true);
Object value = k.get(queryDomain);
String ftype = f.getGenericType().toString();
if (ftype.equals("class java.math.BigDecimal")) {
if ((check(f.get(infoDomain))).compareTo(check(value)) != 0) {
// 变化值的属性名
propNameList.add(f.getName());
}
} else if (!Objects.equals(f.get(infoDomain), value)) {
// 变化值的属性名
propNameList.add(f.getName());
}
}
T editInfo = c.newInstance();
List<Field> editInfolist = Arrays.asList(editInfo.getClass().getDeclaredFields());
Map<String, Field> editInfoMap = editInfolist.stream().collect(Collectors.toMap(Field::getName, p -> p));
for (String name : propNameList) {
// 对editInfo中变化值的属性赋值
Field f = editInfoMap.get(name);
f.setAccessible(true);
Field k = infoMap.get(name);
k.setAccessible(true);
f.set(editInfo, k.get(infoDomain));
}
return editInfo;
}