目前在项目中遇到如下的需求,在项目中有一个定时任务去统计数据,统计出来的数据会存入一张统计表A中,每次统计的时候需要去判断新旧统计数据(两个List),如果原来已经存在的数据进行更新,原来不存在的数据进行新增,原来存在但是新数据中不存在的数据进行删除。于是进行了架构设计,通过使用一个抽象类和一个新旧数据对比处理类来实现这一需求。
抽象类代码如下:
public abstract class HomeReportDataBuilder<T> {
/**
* Render the hash code of operation.
* <p>
* Example: (companyId_serviceId_operation_recordId).hashCode()
* </p>
*
* @param t
* @return
*/
public String renderKey(T t) {
return null;
}
/**
* Render the hash code of operation.
* <p>
* Example: (companyId_新旧数据对比处理类serviceId_operation_recordId).hashCode()
* </p>
*
* @param t
* @return
*/
public String renderUpdateIbatis() {
return null;
}
/**
* Render the hash code of operation.
* <p>
* Example: (companyId_serviceId_operation_recordId).hashCode()
* </p>
*
* @param t
* @return
*/
public String renderAddIbatis() {
return null;
}
/**
* Render the hash code of operation.
* <p>
* Example: (companyId_serviceId_operation_recordId).hashCode()
* </p>
*
* @param t
* @return
*/
public String renderDeleteIbatis() {
return null;
}
}
新旧数据对比处理类代码如下:
public class HomeReportServiceImpl implements HomeReportService {
protected BatchDao batchDao;
public BatchDao getBatchDao() {
return batchDao;
}
public void setBatchDao(BatchDao batchDao) {
this.batchDao = batchDao;
}
public <T extends BaseEntity> void dealData(Map<String, T> currentData, List<T> originalData, HomeReportDataBuilder<T> dataBuilder) {
List<T> updateList = new ArrayList<T>();
List<T> addList = new ArrayList<T>();
List<T> deleteList = new ArrayList<T>();
// separate currentData and originalData to updateList, addList and deleteList
for (T originalItem : originalData) {
String key = dataBuilder.renderKey(originalItem);
// this originalItem has data today, we will update data
if (currentData.containsKey(key)) {
T current = currentData.get(key);
current.setId(originalItem.getId());
updateList.add(current);
currentData.remove(key);
} else {
// if originalItem not exist in map, originalItem need to delete
deleteList.add(originalItem);
}
}
if (!currentData.isEmpty()) {
// if map still has data, these data not exist in database, we should insert these data
for (Entry<String, T> entry : currentData.entrySet()) {
addList.add(entry.getValue());
}
}
int i = 0;
while (i < deleteList.size() && i < addList.size()) {
T item = addList.get(i);
item.setId(deleteList.get(i).getId());
updateList.add(item);
i++;
}
addList = addList.subList(i, addList.size());
deleteList = deleteList.subList(i, deleteList.size());
batchDao.batchDataOperation(updateList, dataBuilder.renderUpdateIbatis());
batchDao.batchDataOperation(addList, dataBuilder.renderAddIbatis());
batchDao.batchDataOperation(deleteList, dataBuilder.renderDeleteIbatis());
}
/**
* @see cn.vobile.trackerspt.service.homereport.HomeReportService#dealData(java.util.List, java.util.List, cn.vobile.trackerspt.service.homereport.HomeReportDataBuilder)
*/
public <T extends BaseEntity> void dealData(List<T> currentData, List<T> originalData, HomeReportDataBuilder<T> dataBuilder) {
Map<String, T> map = new HashMap<String, T>();
for (T data : currentData) {
map.put(dataBuilder.renderKey(data), data);
}
dealData(map, originalData, dataBuilder);
}
}
* 考虑到每个实体的key值会由不同的数据表字段组成,并且每个调用的方法对应的数据表也是不同的,因此在实现两个List对比处理的时候,都要继承抽象类
<span style="color:#FF0000;"><strong>HomeReportDataBuilder<T>并且重写里面的4个方法。</strong></span>