优化SQL脚本轮询函数

This commit is contained in:
houxinyu 2023-09-28 15:27:42 +08:00
parent be932d1584
commit f857c67a16
2 changed files with 25 additions and 16 deletions

View File

@ -23,13 +23,9 @@ import java.util.*;
*/ */
public class ScriptPollingTask implements Runnable { public class ScriptPollingTask implements Runnable {
private static final String SQL_PATTERN = "SELECT {},{} FROM {} WHERE {}=?"; private static final String SCRIPT_PATTERN = "SELECT {},{},{},{} FROM {} WHERE {}=?";
private static final String CONCAT_PATTERN = "CONCAT_WS(':',{},{},{}) as script_concat"; private static final String SCRIPT_PATTERN_WITH_LANGUAGE = "SELECT {},{},{},{},{} FROM {} WHERE {}=?";
private static final String CONCAT_WITH_LANGUAGE_PATTERN = "CONCAT_WS(':',{},{},{},{}) as script_concat";
private static final String SCRIPT_KEY_FIELD = "script_concat";
private Connection conn; private Connection conn;
@ -62,14 +58,16 @@ public class ScriptPollingTask implements Runnable {
String applicationName = sqlParserVO.getApplicationName(); String applicationName = sqlParserVO.getApplicationName();
String scriptLanguageField = sqlParserVO.getScriptLanguageField(); String scriptLanguageField = sqlParserVO.getScriptLanguageField();
String KeyField; String sqlCmd = null;
if (StrUtil.isNotBlank(scriptLanguageField)) { if (StrUtil.isNotBlank(scriptLanguageField)) {
KeyField = StrUtil.format(CONCAT_WITH_LANGUAGE_PATTERN, scriptIdField, scriptTypeField, scriptNameField, scriptLanguageField); //脚本有语言
sqlCmd = StrUtil.format(SCRIPT_PATTERN_WITH_LANGUAGE, scriptDataField, scriptIdField, scriptTypeField, scriptNameField,
scriptLanguageField, scriptTableName, scriptApplicationNameField);
} else { } else {
KeyField = StrUtil.format(CONCAT_PATTERN, scriptIdField, scriptTypeField, scriptNameField); sqlCmd = StrUtil.format(SCRIPT_PATTERN, scriptDataField, scriptIdField, scriptTypeField, scriptNameField,
scriptTableName, scriptApplicationNameField);
} }
String sqlCmd = StrUtil.format(SQL_PATTERN, KeyField, scriptDataField, scriptTableName, scriptApplicationNameField);
stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 设置游标拉取数量 // 设置游标拉取数量
stmt.setFetchSize(FETCH_SIZE_MAX); stmt.setFetchSize(FETCH_SIZE_MAX);
@ -79,7 +77,7 @@ public class ScriptPollingTask implements Runnable {
Set<String> newScriptSet = new HashSet<>(); Set<String> newScriptSet = new HashSet<>();
while (rs.next()) { while (rs.next()) {
String scriptKey = getStringFromResultSet(rs, SCRIPT_KEY_FIELD); String scriptKey = getScriptKeyFromRS(rs, sqlParserVO);
String newData = getStringFromResultSet(rs, scriptDataField); String newData = getStringFromResultSet(rs, scriptDataField);
String newSHA = DigestUtil.sha1Hex(newData); String newSHA = DigestUtil.sha1Hex(newData);
newScriptSet.add(scriptKey); newScriptSet.add(scriptKey);
@ -92,8 +90,7 @@ public class ScriptPollingTask implements Runnable {
//加入到shaMap //加入到shaMap
scriptSHAMap.put(scriptKey, newSHA); scriptSHAMap.put(scriptKey, newSHA);
} } else if (!StrUtil.equals(newSHA, scriptSHAMap.get(scriptKey))) {
else if (!StrUtil.equals(newSHA, scriptSHAMap.get(scriptKey))) {
//SHA值发生变化,表示该script的值已被修改,重新拉取变化的script //SHA值发生变化,表示该script的值已被修改,重新拉取变化的script
NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey); NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey);
//修改script //修改script
@ -106,7 +103,7 @@ public class ScriptPollingTask implements Runnable {
//SHA值无变化,表示该chain未改变 //SHA值无变化,表示该chain未改变
} }
if(scriptSHAMap.size() > newScriptSet.size()) { if (scriptSHAMap.size() > newScriptSet.size()) {
//如果遍历prepareStatement后修改过的SHAMap数量比最新script总数多, 说明有两种情况 //如果遍历prepareStatement后修改过的SHAMap数量比最新script总数多, 说明有两种情况
// 1删除了script // 1删除了script
// 2修改了script的id/name/type:因为遍历到新的script_key时会加到SHAMap里,但没有机会删除旧的script // 2修改了script的id/name/type:因为遍历到新的script_key时会加到SHAMap里,但没有机会删除旧的script
@ -114,7 +111,7 @@ public class ScriptPollingTask implements Runnable {
//在此处遍历scriptSHAMap,把不在newScriptSet中的script删除 //在此处遍历scriptSHAMap,把不在newScriptSet中的script删除
//这里用iterator是为避免在遍历集合时删除元素导致ConcurrentModificationException //这里用iterator是为避免在遍历集合时删除元素导致ConcurrentModificationException
Iterator<String> iterator = scriptSHAMap.keySet().iterator(); Iterator<String> iterator = scriptSHAMap.keySet().iterator();
while(iterator.hasNext()){ while (iterator.hasNext()) {
String scriptKey = iterator.next(); String scriptKey = iterator.next();
if (!newScriptSet.contains(scriptKey)) { if (!newScriptSet.contains(scriptKey)) {
NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey); NodeConvertHelper.NodeSimpleVO scriptVO = NodeConvertHelper.convert(scriptKey);
@ -142,4 +139,16 @@ public class ScriptPollingTask implements Runnable {
} }
return data; return data;
} }
private String getScriptKeyFromRS(ResultSet rs, SQLParserVO sqlParserVO) throws SQLException {
String id = getStringFromResultSet(rs, sqlParserVO.getScriptIdField());
String type = getStringFromResultSet(rs, sqlParserVO.getScriptTypeField());
String name = getStringFromResultSet(rs, sqlParserVO.getScriptNameField());
String scriptKey = StrUtil.join(":", id, type, name);
if (StrUtil.isNotBlank(sqlParserVO.getScriptLanguageField())) {
String language = getStringFromResultSet(rs, sqlParserVO.getScriptLanguageField());
scriptKey = StrUtil.join(":", id, type, name, language);
}
return scriptKey;
}
} }

View File

@ -148,7 +148,7 @@ public class SQLWithXmlELSpringbootPollingTest extends BaseTest {
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
//修改script data //修改script data
statement.executeUpdate( statement.executeUpdate(
"UPDATE SCRIPT_NODE_TABLE SET SCRIPT_NODE_DATA='return false;' WHERE SCRIPT_NODE_ID='x1'"); "UPDATE SCRIPT_NODE_TABLE SET SCRIPT_NODE_DATA='return false' WHERE SCRIPT_NODE_ID='x1'");
//修改script名 //修改script名
statement.executeUpdate( statement.executeUpdate(
"UPDATE SCRIPT_NODE_TABLE SET SCRIPT_NODE_NAME='x0_script' WHERE SCRIPT_NODE_ID='x0'"); "UPDATE SCRIPT_NODE_TABLE SET SCRIPT_NODE_NAME='x0_script' WHERE SCRIPT_NODE_ID='x0'");