片段一
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.ReflectUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.scripting.xmltags.*;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class NullPointFieldAdd implements Interceptor {
ConcurrentMap<String, Map<String, SqlNode>> concurrentMap = new ConcurrentHashMap<>();
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
FieldNullUpdate fieldNullUpdate = new FieldNullUpdate();
Map<String, String> dirtyValueMap = new HashMap<>();
MappedStatement statement = (MappedStatement) args[0];
ResultMap resultMap = statement.getResultMaps().get(0);
if (!resultMap.getId().endsWith("updateById-Inline")) {
return invocation.proceed();
}
String id = statement.getId();
Map<String, SqlNode> stringSqlNodeMap = concurrentMap.get(id);
if (stringSqlNodeMap == null) {
stringSqlNodeMap = new ConcurrentHashMap<>();
concurrentMap.put(id, stringSqlNodeMap);
changeStatement(statement.getSqlSource(), stringSqlNodeMap);
}
stringSqlNodeMap.forEach((fieldName, sqlNode) -> {
if (fieldNullUpdate.nullUpdateFlag(fieldName)) {
String test = (String) ReflectUtil.getFieldValue(sqlNode, "test");
dirtyValueMap.put(fieldName, test);
ReflectUtil.setFieldValue(sqlNode, "test", "true");
}
});
try {
return invocation.proceed();
} finally {
if (CommonUtil.isNotEmpty(dirtyValueMap.keySet())) {
for (String key : dirtyValueMap.keySet()) {
ReflectUtil.setFieldValue(stringSqlNodeMap.get(key), "test", dirtyValueMap.get(key));
}
}
dirtyValueMap.clear();
}
}
private void changeStatement(SqlSource sqlSource, Map<String, SqlNode> stringSqlNodeMap) throws Exception {
SqlNode rootNode = (SqlNode) ReflectUtil.getFieldValue(sqlSource, "rootSqlNode");
if (rootNode instanceof MixedSqlNode) {
List<SqlNode> sqlNodes = (List) ReflectUtil.getFieldValue(rootNode, "contents");
for (SqlNode sqlNode : sqlNodes) {
if (sqlNode instanceof SetSqlNode) {
SetSqlNode setSqlNode = (SetSqlNode) sqlNode;
SqlNode setSqlNode2 = (SqlNode) ReflectUtil.getFieldValue(setSqlNode, "contents");
if (setSqlNode2 instanceof MixedSqlNode) {
List<SqlNode> updateSqlNodes = (List) ReflectUtil.getFieldValue(setSqlNode2, "contents");
for (SqlNode updateSqlNode : updateSqlNodes) {
if (updateSqlNode instanceof IfSqlNode) {
String test = (String) ReflectUtil.getFieldValue(updateSqlNode, "test");
String content = ReUtil.get("'(.*)'", test, 1);
stringSqlNodeMap.put(content, updateSqlNode);
}
}
}
}
}
}
}
片段二
import java.util.ArrayList;
import java.util.List;
public class FieldNullUpdate {
static ThreadLocal<List<String>> fields = new ThreadLocal<List<String>>(){
@Override
protected List<String> initialValue() {
return new ArrayList<String>();
}
};
public static void addNullFields(String... fileds){
for (String field : fileds){
fields.get().add(field);
}
}
public boolean nullUpdateFlag(String field){
return fields.get().contains(field);
}
public void clear(){
fields.remove();
}
片段三
public class MybatisNullAdd {
public static void addNullField(String... fields){
FieldNullUpdate.addNullFields(fields);
}
}
Order updateOrder = new Order();
updateOrder.setId(1);
MybatisNullAdd.addNullField("orderCode");
orderMapper.updateById(updateOrder);