一、on duplicate key update
(1)on duplicate key update 语句根据主键id或唯一键来判断当前插入是否已存在。
(2)记录已存在时,只会更新on duplicate key update之后指定的字段。
(3)如果同时传递了主键和唯一键,以主键为判断存在依据,唯一键字段内容可以被修改。
二、递归循环栈溢出
场景:重试
问题代码
@Async
public ConfigInfoDO getVersion(Integer configNum,Integer size) {
ConfigInfoDO configInfoDO = configMapper.selectConfigInfo();
ConfigInfoDO newConfigInfoDo = new ConfigInfoDO();
newConfigInfoDo.setId(configInfoDO.getId());
switch (configNum) {
case 1:
newConfigInfoDo.setVersion(configInfoDO.getVersion());
break;
default:
log.warn("不存在,请先添加");
}
try {
configMapper.updateConfig(newConfigInfoDo,size);
} catch (RuntimeException e) {
return getVersion(configNum,size);
}
return newConfigInfoDo;
}
解决方案:
1.把递归调用函数改用while或者for循环来实现 。
2.通过尾递归优化。
3.改用堆内存,函数里定义很大的局部变量(例如大数组),这种情况可以将局部变量改为静态变量(实质上也是全局变量)。
4.增大栈的大小值。
这里采用方法1 ,修改后代码如下
public ConfigInfoDO test(Integer configNum,Integer size, String deviceMac) {
Integer tryCount = 10;
while (tryCount-- > 0) {
ConfigInfoDO configInfoDO = getVersion(configNum, size, deviceMac);
if (configInfoDO != null) {
return configInfoDO;
}
}
log.error("获取连续失败{}次,返回null");
return null;
}
@Async
public ConfigInfoDO getVersion(Integer configNum,Integer size) {
ConfigInfoDO configInfoDO = configMapper.selectConfigInfo();
ConfigInfoDO newConfigInfoDo = new ConfigInfoDO();
newConfigInfoDo.setId(configInfoDO.getId());
switch (configNum) {
case 1:
newConfigInfoDo.setVersion(configInfoDO.getVersion());
break;
default:
log.warn("不存在,请先添加");
}
try {
configMapper.updateConfig(newConfigInfoDo,size);
} catch (RuntimeException e) {
return null;
}
return newConfigInfoDo;
}
三、异步结果返回
场景:前端调接口先返回结果,在执行后台逻辑
@Resource
public ThreadPoolTaskExecutor taskExecutor;
@Override
public void update() {
taskExecutor.execute(() -> {
你的逻辑代码
})
}
四、调第三方接口,requestBody为JsonArray
List<LinkDTO> factoryList = new ArrayList<>();
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(factoryList));
JSONObject data = new JSONObject();
data.put("factoryList", jsonArray);
网友评论