适用约束:
虽然更新很快,但是也有约束, 必须保证更新的字段要统一,如果不同意就会漏更新,或者报错.
最近发现一个问题:
执行这个更新方法后,马上查询, 查询到的是更新前的数据.
表结果
CREATE TABLE `t_a` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a1` varchar(255) DEFAULT NULL,
`a2` varchar(255) DEFAULT NULL,
`a3` varchar(255) DEFAULT NULL,
`c` datetime DEFAULT CURRENT_TIMESTAMP,
`u` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
批量更新
INSERT INTO t_a (
id,a1,a2,a3
)
VALUES
( 1,'11','121','131' ),
( 2,'21','22','23' )
ON DUPLICATE KEY UPDATE
a1 = VALUES(a1),
a2 = VALUES(a2)
讲解
##第一部分:需要注意的是 =>一定要带唯一主键的字段,没带就只会新增不会修改
INSERT INTO t_a (
id,a1,a2,a3
)
VALUES
( 1,'11','121','131' ),
( 2,'21','22','23' )
##第二部分:这列出来的是需要修改的字段,不想被修改就不要在这里加,不管a3值是否变化,值都不会被修改
a1 = VALUES(a1),
a2 = VALUES(a2)
mybatis中的使用
insert into t_a
(id,a1,a2,a3)
values
(#{item.id},
#{item.a1},
#{item.a2},
#{item.a3})
ON DUPLICATE KEY UPDATE
a1 = VALUES(a1),
a2 = VALUES(a2)
无法做到动态判断是否有值,且需要修改,方法调整 --- 笨办法
INSERT INTO t_a (
${columnList}
) VALUES
( ${insertColumnList} )
ON DUPLICATE KEY UPDATE ${updateColumnList}
备注:
columnList:需要更新的字段(检查对象中不为null的字段集合,例如:id,a1,a2,a3)
insertColumnList:在对象中取值的字符串,更columnList对应,例如:#{item.id},#{item.a1},#{item.a2},#{item.a3}
updateColumnList:修改更新的字段集合,例如:a1 = VALUES(a1),a2 = VALUES(a2)
疑惑
这个sql执行返回值并不是被修改的条数,有点费解
配套适用的 getColumnListByNotNull
拙劣的封装,不喜勿喷...
/**
* on duplicate key update 修改需要的对象
* @param list 处理集合
* @param 处理对象
* @return 获取有效字段
*/
public static List getColumnListByNotNull(List list) {
// 不处理
if(CollectionUtils.isEmpty(list)){
log.error("getColumnListByNotNull处理集合为空");
return Lists.newArrayList();
}
// 取其中一条记录来确认需要修改字段
T t = list.get(0);
// 获取全部属性
List allFieldsList = FieldUtils.getAllFieldsList(t.getClass());
// 排除非静态属性 + 非空值对象
List columnListByNotNull = allFieldsList.stream().filter(f -> {
try {
f.setAccessible(true);
// 排除静态属性
if (Modifier.isStatic(f.getModifiers())) {
return false;
}
return null != f.get(t);
} catch (IllegalAccessException e) {
e.printStackTrace();
log.error("getColumnListByNotNull异常2", e);
return false;
}
}).map(Field::getName).collect(Collectors.toList());
// 异常情况
if (CollectionUtils.isEmpty(columnListByNotNull)) {
log.error("对象中包含非null属性个数为0,getColumnListByNotNull = {}", JSON.toJSONString(t));
throw new PlatformException("对象中包含非null属性个数为0");
}
if (!columnListByNotNull.contains("id")) {
log.error("对象中id的值为null,getColumnListByNotNull = {}", JSON.toJSONString(t));
throw new PlatformException("对象中id的值为null");
}
// 组装
String columnList = String.join(",", columnListByNotNull);
log.info("on duplicate key update => columnList={}", columnList);
String updateColumnList = columnListByNotNull.stream().map(n -> n.concat("=").concat("values(").concat(n).concat(")")).collect(Collectors.joining(","));
log.info("on duplicate key update => updateColumnList={}", updateColumnList);
String insertColumnList = columnListByNotNull.stream().map(n -> "#{item.".concat(n).concat("}")).collect(Collectors.joining(","));
log.info("on duplicate key update => updateColumnList={}", insertColumnList);
return Lists.newArrayList(columnList, updateColumnList, insertColumnList);
}