Skip to content

优化plugin/datasource模块下AbstractMapper类的insert、update方法。使得方法的逻辑更加清晰,提升程序性能 #13493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 16, 2025

Conversation

20144101037
Copy link
Contributor

Please do not create a Pull Request without creating an issue first.

What is the purpose of the change

XXXXX

Brief changelog

XX

Verifying this change

XXXX

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Make sure there is a Github issue filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
  • Format the pull request title like [ISSUE #123] Fix UnknownException when host config not exist. Each commit in the pull request should have a meaningful subject line and body.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add integration-test in test module.
  • Run mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true to make sure basic checks pass. Run mvn clean install -DskipITs to make sure unit-test pass. Run mvn clean test-compile failsafe:integration-test to make sure integration-test pass.

20144101037 and others added 7 commits December 4, 2024 10:45
…eature/optimize-code-js

# Conflicts:
#	plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/AbstractMapper.java
#	plugin/datasource/src/test/java/com/alibaba/nacos/plugin/datasource/mapper/AbstractMapperTest.java
…ate方法进行重构,使得逻辑更清晰,避免嵌套循环和冗余判断条件
Copy link

Thanks for your this PR. 🙏
Please check again for your PR changes whether contains any usage/api/configuration change such as Add new API , Add new configuration, Change default value of configuration.
If so, please add or update documents(markdown type) in docs/next/ for repository nacos-group/nacos-group.github.io


感谢您提交的PR。 🙏
请再次查看您的PR内容,确认是否包含任何使用方式/API/配置参数的变更,如:新增API新增配置参数修改默认配置等操作。
如果是,请确保在提交之前,在仓库nacos-group/nacos-group.github.io中的docs/next/目录下添加或更新文档(markdown格式)。

Copy link

lingma-agents bot commented Jun 10, 2025

优化AbstractMapper类的insert/update方法并新增测试用例

变更文件

文件路径 变更说明
plugin/​datasource/​src/​main/​java/​com/​alibaba/​nacos/​plugin/​datasource/​mapper/​AbstractMapper.java 将insert/update方法的字符串拼接方式从StringBuilder改为StringJoiner,优化了列名和值的分隔符处理。新增对列名@函数格式的解析能力,通过split("@",2)限制分割次数,使用getFunction处理特殊函数表达式。简化了循环中的索引判断逻辑,移除了多余的StringBuilder初始化步骤。
plugin/​datasource/​src/​test/​java/​com/​alibaba/​nacos/​plugin/​datasource/​mapper/​AbstractMapperTest.java 新增testInsertContainsAt和testUpdateContainsAt测试用例,验证列名后跟@函数语法的正确处理。测试数据包含NOW()等函数表达式,验证生成的SQL语句中函数替换和问号占位符的正确性。扩展测试数据使用Arrays.asList和Collections工具类。

时序图

sequenceDiagram
    participant AM as AbstractMapper
    participant SJ as StringJoiner
    participant SB as StringBuilder
    AM->>SJ: create StringJoiner for columns
    AM->>SJ: add column parts[0]
    AM->>SJ: create value Joiner with getFunction(parts[1])
    SJ-->>AM: generate column/value strings
    AM->>SB: build final SQL with table name
    AM->>AM: appendWhereClause处理where条件
    note right of AM: 新增@符号解析逻辑<br>动态处理函数表达式
Loading

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @Lingma-Agent 分析这个方法的性能瓶颈并提供优化建议。

  • @Lingma-Agent 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @Lingma-Agent 请总结上述讨论并提出解决方案。

  • @Lingma-Agent 请根据讨论内容生成优化代码。

Copy link

@lingma-agents lingma-agents bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 代码评审报告

🎯 评审意见概览

严重度 数量 说明
🔴 Blocker 0 阻断性问题,需立即修复。例如:系统崩溃、关键功能不可用或严重安全漏洞。
🟠 Critical 0 严重问题,高优先级修复。例如:核心功能异常或性能瓶颈影响用户体验。
🟡 Major 0 主要问题,建议修复。例如:非核心功能缺陷或代码维护性较差。
🟢 Minor 1 次要问题,酌情优化。例如:代码格式不规范或注释缺失。

总计: 1 个问题


📋 评审意见详情

💡 单文件建议

以下是文件级别的代码建议,聚焦于代码的可读性、可维护性和潜在问题。
☕ plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/AbstractMapper.java (1 💬)

🚀 跨文件建议

以下是对代码架构和设计的综合分析,聚焦于跨文件交互、系统一致性和潜在优化空间。
🔍 1. 重复代码导致的可维护性风险

insert和update方法中对列名@符号的分割逻辑存在重复代码。两个方法均使用String[] parts = col.split("@", 2)处理列定义,但未提取公共方法。这种重复会导致未来维护时需要同步修改两处代码,增加出错风险。建议将该逻辑封装为protected方法,供两个方法调用。

📌 关键代码:

String[] parts = col.split("@", 2); // insert方法
String[] parts = col.split("@", 2); // update方法

⚠️ 潜在风险: 未来若修改@符号的处理规则,需要同时修改两个地方,容易遗漏导致bug。

🔍 2. 潜在SQL注入风险

getFunction(parts[1])的返回值直接拼接到SQL字符串中,若columns参数来自外部输入且未经过滤,可能存在SQL注入风险。需要确认columns参数来源是否为可信数据,或对parts[1]进行参数化处理/白名单校验。

📌 关键代码:

valueJoiner.add(parts.length > 1 ? getFunction(parts[1]) : "?");

⚠️ 潜在风险: 若攻击者构造恶意列定义,可能导致非法SQL执行。

🔍 3. 测试覆盖不完整

新增测试用例未覆盖@符号缺失或多余分割的情况。例如:当列定义中没有@符号时,或包含多个@符号时(如"col@a@b"),需要验证是否符合预期行为。当前测试仅验证了标准用例。

📌 关键代码:

testInsertContainsAt 测试仅验证标准用例

⚠️ 潜在风险: 未处理的边界情况可能导致生产环境SQL语法错误。

🔍 4. 架构一致性问题

新增的StringJoiner用法与项目其他SQL生成代码存在模式差异。需要确认项目中是否统一使用StringJoiner,或是否存在其他SQL构建工具(如MyBatis)未被考虑。

📌 关键代码:

StringJoiner columnJoiner = new StringJoiner(...);

⚠️ 潜在风险: 与现有SQL生成模式不一致可能导致维护者困惑,增加集成难度。


💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @Lingma-Agent 分析这个方法的性能瓶颈并提供优化建议。

  • @Lingma-Agent 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @Lingma-Agent 请总结上述讨论并提出解决方案。

  • @Lingma-Agent 请根据讨论内容生成优化代码。

Comment on lines 56 to 68
String[] parts = col.split("@", 2); // 最多分割成两部分
columnJoiner.add(parts[0]);
valueJoiner.add(parts.length > 1 ? getFunction(parts[1]) : "?");
}
sql.append(")");
return sql.toString();

return "INSERT INTO " + getTableName() + columnJoiner + " VALUES" + valueJoiner;
}

@Override
public String update(List<String> columns, List<String> where) {
StringBuilder sql = new StringBuilder();
String method = "UPDATE ";
sql.append(method);
sql.append(getTableName()).append(" ").append("SET ");

for (int i = 0; i < columns.size(); i++) {
String[] parts = columns.get(i).split("@");
String column = parts[0];
if (parts.length == 2) {
sql.append(column).append(" = ").append(getFunction(parts[1]));
} else {
sql.append(column).append(" = ").append("?");
}
if (i != columns.size() - 1) {
sql.append(",");
}
StringJoiner setJoiner = new StringJoiner(",");
for (String col : columns) {
String[] parts = col.split("@", 2);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

将硬编码的分隔符'@'替换为常量定义,提升代码可维护性

🟢 Minor | 🧹 Code Smells

📋 问题详情

代码中直接使用字符串'@'作为分隔符,未定义为常量。硬编码的魔法字符串会影响代码可维护性和可读性,当需要修改分隔符时需全局搜索替换,存在维护风险。建议将分隔符定义为类级别常量以提高规范性。

💡 解决方案

将分隔符定义为类常量:

+ private static final String COLUMN_SEPARATOR = "@";

- String[] parts = col.split("@", 2);
+ String[] parts = col.split(COLUMN_SEPARATOR, 2);

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

KomachiSion
KomachiSion previously approved these changes Jun 11, 2025
@KomachiSion
Copy link
Collaborator

@20144101037 CI没有通过

@20144101037 20144101037 requested a review from KomachiSion June 11, 2025 13:19
@20144101037
Copy link
Contributor Author

@20144101037 CI没有通过

重新做了提交,麻烦您再看下

@wuyfee
Copy link

wuyfee commented Jun 12, 2025

$\color{red}{FAILURE}$
DETAILS
✅ - docker: success
❌ - deploy (standalone & cluster & standalone_auth): failure
❌ - e2e-java-test (standalone & cluster & standalone_auth): skipped
❌ - e2e-go-test (standalone & cluster): skipped
❌ - e2e-cpp-test (standalone & cluster): skipped
❌ - e2e-csharp-test (standalone & cluster): skipped
❌ - e2e-nodejs-test (standalone & cluster): skipped
❌ - e2e-python-test (standalone & cluster): skipped
✅ - clean (standalone & cluster & standalone_auth): success

@20144101037
Copy link
Contributor Author

@20144101037 CI没有通过

@KomachiSion 看了CI报错原因,不是这一次提交代码导致的问题

@KomachiSion
Copy link
Collaborator

@20144101037 CI没有通过

@KomachiSion 看了CI报错原因,不是这一次提交代码导致的问题

同步一下develop分支的代码再试试

@20144101037
Copy link
Contributor Author

20144101037 commented Jun 13, 2025

@20144101037 CI没有通过

@KomachiSion 看了CI报错原因,不是这一次提交代码导致的问题

同步一下develop分支的代码再试试

好的,已同步最新develop分支代码,并push到个人分支

@wuyfee
Copy link

wuyfee commented Jun 16, 2025

$\color{red}{FAILURE}$
DETAILS
✅ - docker: success
❌ - deploy (standalone & cluster & standalone_auth): failure
❌ - e2e-java-test (standalone & cluster & standalone_auth): skipped
❌ - e2e-go-test (standalone & cluster): skipped
❌ - e2e-cpp-test (standalone & cluster): skipped
❌ - e2e-csharp-test (standalone & cluster): skipped
❌ - e2e-nodejs-test (standalone & cluster): skipped
❌ - e2e-python-test (standalone & cluster): skipped
✅ - clean (standalone & cluster & standalone_auth): success

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants