【开发心得】记录一次同步记录脚本的编写过程。
前言:项目落地尾声,数据的持续同步是一个比较痛苦的问题,本身iptv领域有c1~c4四个数据传输协议,如果只是通过接口下发和接收来同步数据的话,倒还好说,主要问题在于,如何处理无法下发并且需要同步的数据。
数据同步步骤:
0.我方将新系统使用的数据导出,并且建议与就系统数据相关的关联关系表。
1.客户将旧系统使用的分类数据导出。我方拿到导出数据,建立关联关系。
2.客户持续导出分类与内容的编排关系到服务器的某个位置。
3.我方借助Java小工程(Springboot快速编写)。细节步骤:
a.ftp拉取目标文件
b.一次IO读取(数据量在5w左右),使用List承接,借助工具类拆分数据为每1000条一组,避免一次插入造成大量的数据回滚和内存压力。
工具类代码如下,切分List:
package com.bytue.ma_vod.modules.macenter.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @param <T> 泛型
*/
public class SubListUtil<T> {
private static final Logger logger = LoggerFactory.getLogger(SubListUtil.class);
/**
* 截取list集合,返回list集合
* @param tList (需要截取的集合)
* @param subNum (每次截取的数量)
* @return
*/
public static<T> List<List<T>> subList(List<T> tList, Integer subNum) {
// 新的截取到的list集合
List<List<T>> tNewList = new ArrayList<List<T>>();
// 要截取的下标上限
Integer priIndex = 0;
// 要截取的下标下限
Integer lastIndex = 0;
// 每次插入list的数量
// Integer subNum = 500;
// 查询出来list的总数目
Integer totalNum = tList.size();
// 总共需要插入的次数
Integer insertTimes = totalNum / subNum;
List<T> subNewList = new ArrayList<T>();
for (int i = 0; i <= insertTimes; i++) {
// [0--20) [20 --40) [40---60) [60---80) [80---100)
priIndex = subNum * i;
lastIndex = priIndex + subNum;
// 判断是否是最后一次
if (i == insertTimes) {
logger.info("最后一次截取:"+priIndex + "," + lastIndex);
subNewList = tList.subList(priIndex, tList.size());
} else {
// 非最后一次
subNewList = tList.subList(priIndex, lastIndex);
}
if (subNewList.size() > 0) {
//logger.info("开始将截取的list放入新的list中");
tNewList.add(subNewList);
}
}
return tNewList;
}
/**
* 截取list集合,返回map集合
* @param tList (需要截取的集合)
* @param subNum (每次截取的数量)
* @return
*/
public static<T> Map<Integer, List<T>> subListToMap(List<T> tList, Integer subNum) {
// 新的截取到的list集合
//List<List<T>> tNewList = new ArrayList<List<T>>();
Map<Integer, List<T>> newTlsMap = new HashMap<Integer, List<T>>();
// 要截取的下标上限
Integer priIndex = 0;
// 要截取的下标下限
Integer lastIndex = 0;
// 每次插入list的数量
// Integer subNum = 500;
// 查询出来list的总数目
Integer totalNum = tList.size();
// 总共需要插入的次数
Integer insertTimes = totalNum / subNum;
List<T> subNewList = new ArrayList<T>();
for (int i = 0; i <= insertTimes; i++) {
// [0--20) [20 --40) [40---60) [60---80) [80---100)
priIndex = subNum * i;
lastIndex = priIndex + subNum;
// 判断是否是最后一次
if (i == insertTimes) {
//logger.info(priIndex + "," + tList.size());
//logger.info("--------------------------------------");
subNewList = tList.subList(priIndex, tList.size());
} else {
// 非最后一次
//logger.info("最后一次截取:"+priIndex + "," + lastIndex);
//logger.info("***************************************");
subNewList = tList.subList(priIndex, lastIndex);
}
if (subNewList.size() > 0) {
//logger.info("开始将截取的list放入新的list中");
newTlsMap.put(i, subNewList);
}
}
return newTlsMap;
}
}
c.mybatis foreach分批导入,每次1000条,至于mybatis foreach的使用,网上有很多教程,也属于mybatis基础必备,请务必掌握。
d.删除原来的分类与内容的关联关系。
e.重新建立与分类与内容的关联关系。
f.更新内容数据的状态。
g.删除trigger.
h. 删除重新关联的数据的审核记录。
i.插入符合要求的审核记录。
j.重新补全trigger.
上述过程中有两个要点,一个是数据库的关联更新 和 删除语法,示例如下:
关联更新:
update table1 p join table2 m on p.code = m.programcode
set p.curcontaudit = 'end',p.examinetype = '2',p.acl_flowtype = '0',p.acl_logrejectflag = '1',examinetype='4'
关联删除:
delete t1 from ma_vod_audit_circulation_log t1, temp_categorymapping2 t2
where t1.id = t2.programcode
and t1.beforetype = 'end' and t1.aftertype = 'xml_0'
另一个是,使用mybatis执行dml语句,比如 trunct 表和删除trigger,新增trigger,这个是可以直接支持的。
使用trunct要注意的是使用@update注解或者 update标签(xml)。