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

Java读取宝可梦SQL数据库行存入数组时遇到问题

问题分析与修复方案

看起来你在把宝可梦数据库的查询结果存入数组时遇到了麻烦,我来拆解下代码里的潜在问题,再给你调整后的方案:

首先看SQL查询部分的隐患

你的原始查询语句是:

String query2 = "SELECT * " + "FROM Pokedex.typea, Pokedex.Pokemon where Pokemon.ID = " + pk + " AND type1 = type_name";

这里有两个明显的问题:

  • SQL注入风险:直接拼接pk参数到SQL里,如果pk是用户输入的内容,很容易被注入恶意代码,而且如果pk是字符串类型还会触发语法错误。
  • 隐式连接可读性差:用逗号分隔表的旧语法容易混淆连接条件,换成显式INNER JOIN能让逻辑更清晰,减少出错概率。

然后是ResultSet处理的问题

你的结果集遍历代码:

int i = 2;
while(rs2.next() && i<19) {
    weaka[i-2] = rs2.getInt(i);
    System.out.print...
}

这里的逻辑有点混乱:

  • rs2.next()是移动到下一行数据,而i是列的索引,你把行遍历和列遍历混在一起了——如果查询返回多行,每次循环i都会递增,很快就会超出数组长度或者结果集的列数,抛出异常。
  • 直接依赖SELECT *的列顺序非常脆弱,如果表结构有变化(比如新增/删除列),列索引会直接错位,导致取到错误的数据。
  • 没有做数组越界检查,如果weaka的长度小于17(i从2到18对应17个元素),会直接抛出ArrayIndexOutOfBoundsException。

修正后的代码示例

1. 改用PreparedStatement+显式JOIN

// 明确指定需要的列(推荐,避免*带来的列顺序问题),或者用t.*, p.*
String query2 = "SELECT t.*, p.* "
                + "FROM Pokedex.Pokemon p "
                + "INNER JOIN Pokedex.typea t ON p.type1 = t.type_name "
                + "WHERE p.ID = ?";

// 使用PreparedStatement避免注入,自动处理参数类型
PreparedStatement pst = con.prepareStatement(query2);
pst.setInt(1, pk); // 如果pk是字符串类型,换成pst.setString(1, pk)
ResultSet rs2 = pst.executeQuery();

2. 正确处理ResultSet并存入数组

假设你需要从结果集的第2列开始,取到第18列存入weaka数组:

int arrayIndex = 0;
// 如果你的查询只返回一行数据(根据ID查询通常是单行),用if代替while更合理
if (rs2.next()) {
    ResultSetMetaData metaData = rs2.getMetaData();
    int totalColumns = metaData.getColumnCount();
    
    // 从第2列遍历到第18列,同时检查数组是否还有空间
    for (int colIndex = 2; colIndex <= 18 && arrayIndex < weaka.length; colIndex++) {
        // 这里可以先判断列是否为int类型,避免类型转换错误
        if (metaData.getColumnType(colIndex) == Types.INTEGER) {
            weaka[arrayIndex++] = rs2.getInt(colIndex);
        } else {
            // 非int类型的列可以做默认值处理,比如weaka[arrayIndex++] = 0;
            System.out.println("列" + colIndex + "不是整数类型,跳过");
        }
    }
}

// 记得关闭资源,最好用try-with-resources语法自动关闭,避免内存泄漏
rs2.close();
pst.close();

调试小技巧

如果还是不确定哪里出问题,可以打印结果集的元数据,看看实际返回的列信息:

ResultSetMetaData meta = rs2.getMetaData();
int columnCount = meta.getColumnCount();
for (int j = 1; j <= columnCount; j++) {
    System.out.println("列索引" + j + ": " + meta.getColumnName(j) + ",类型:" + meta.getColumnTypeName(j));
}

这样能清晰看到SELECT *返回的所有列的顺序和类型,避免取错列或者类型不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:08:20