You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API的SQL查询中使用getSites()返回的字符串值

解决方法:调用getSites()填充SQL查询并修复潜在问题

咱们一步步来解决你的问题,同时顺便修复代码里的几个小隐患:


1. 调用getSites()获取站点列表

因为getSites()是ReadCSVFile类的静态方法,你可以直接在GFNSService的getRigStatistics方法里调用它。首先要确保你已经导入了ReadCSVFile类(如果它不在com.gds.service包下的话):

// 替换成ReadCSVFile实际所在的包路径
import your.package.ReadCSVFile;

然后在构建SQL查询前,获取站点字符串:

@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("/getRigStatistics")
public List getRigStatistics(@HeaderParam("authorization") String authString) {
    logger.info("API method getRigStatistics invoked.");
    if (!isAppDynamicsUserAuthenticatedRigStatistics(authString)) {
        throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build());
    }
    List rigList = new ArrayList<>();
    
    // 关键:调用getSites()获取CSV中的站点列表
    String sites = ReadCSVFile.getSites();
    
    // 接下来构建SQL查询...

2. 安全构建SQL查询(重点!)

你原来的SQL拼接方式有两个问题:

  • 语法错误:Site_Name是字符串类型,IN子句里的每个值需要用单引号包裹
  • 严重的SQL注入风险:如果CSV里的站点名称包含特殊字符(比如'),会导致SQL语法错误,甚至被恶意利用

推荐方案:使用PreparedStatement(完全避免注入)

这是最安全的做法,动态生成参数占位符:

// 将逗号分隔的字符串转为站点列表
List<String> siteList = Arrays.asList(sites.split(","));

// 构建带占位符的SQL语句
StringBuilder queryBuilder = new StringBuilder("SELECT NodeID, Site_Name FROM csproperties WHERE Site_Name IN (");
for (int i = 0; i < siteList.size(); i++) {
    if (i > 0) {
        queryBuilder.append(", ");
    }
    queryBuilder.append("?"); // 占位符
}
queryBuilder.append(") ORDER BY Site_Name");

// 假设你已经获取了数据库连接connection
PreparedStatement pstmt = connection.prepareStatement(queryBuilder.toString());

// 给每个占位符设置参数
for (int i = 0; i < siteList.size(); i++) {
    pstmt.setString(i + 1, siteList.get(i).trim()); // 去除站点名称前后的空格
}

// 执行查询并处理结果
ResultSet rs = pstmt.executeQuery();
// ... 这里写你的结果映射代码,把rs的数据转成rigList

备选方案:手动拼接(仅当确定站点内容绝对安全时使用)

如果你能保证CSV里的站点名称不会包含单引号等特殊字符,可以手动给每个值加单引号:

// 给每个站点名称添加单引号,并用逗号分隔
String formattedSites = Arrays.stream(sites.split(","))
                             .map(site -> "'" + site.trim() + "'")
                             .collect(Collectors.joining(","));

// 构建最终的SQL查询
String query = "SELECT NodeID, Site_Name FROM csproperties WHERE Site_Name IN (" + formattedSites + ") ORDER BY Site_Name";

3. 修复getSites()方法的潜在bug

你的getSites()方法有个问题:如果CSV文件为空,sites.substring(0, sites.length() - 1)会抛出StringIndexOutOfBoundsException。另外,用字符串拼接效率很低,建议改成StringBuilder:

public class ReadCSVFile {
    public static String getSites() {
        String csvFile = "C:\\data.csv";
        BufferedReader br = null;
        String line = "";
        StringBuilder sitesBuilder = new StringBuilder(); // 用StringBuilder更高效
        
        try {
            br = new BufferedReader(new FileReader(csvFile));
            while ((line = br.readLine()) != null) {
                String trimmedLine = line.trim();
                if (trimmedLine.isEmpty()) {
                    continue; // 跳过空行
                }
                if (sitesBuilder.length() > 0) {
                    sitesBuilder.append(",");
                }
                sitesBuilder.append(trimmedLine);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return ""; // 或者抛出自定义异常,让上层处理
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sitesBuilder.toString();
    }
}

这样既避免了空文件的异常,又提升了字符串拼接的效率。

内容的提问来源于stack exchange,提问作者Manu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:16:03