未填充数组

ghhaqwfi  于 2021-07-05  发布在  Java
关注(0)|答案(2)|浏览(349)

当我在稍后阶段查看它时,数组中应该至少有3个条目,但它只显示一个条目。我相信这是个有问题的方法,有什么建议吗?

String[] getKidsNamebyCid(int cid) {
        String[] out = new String[20];
        try {
            String qry = "SELECT KIDSNAME FROM TBLKIDS WHERE CID = ?";//setting query command
            ps = connect.prepareStatement(qry);//preparing statement
            ps.setInt(1, cid);//setting CID
            ps.executeQuery();//running command
            int i = 0;
            while (ps.getResultSet().next()) {
                out[i] = ps.getResultSet().getString("KIDSNAME");
                i++;
            }
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return out;
    }
e3bfsja2

e3bfsja21#

你需要学会 PreparedStatement 实际上很管用。我强烈建议您按照教程学习如何使用它,然后按照自己的代码模式。
但它也都在文档中,所以让我们引用各种相关的部分。
的javadoc executeQuery() 说:
执行此中的sql查询 PreparedStatement 对象并返回 ResultSet 查询生成的对象。
问题中的代码此时已经是错误的,因为它**忽略了 executeQuery() 打电话。
另外,javadoc getResultSet() 说:
将当前结果检索为 ResultSet 对象。每个结果只能调用一次此方法。
问题中的代码在这一点上更是错误的,因为它调用 getResultSet() 在循环中重复。
如果您已经阅读了javadoc中所使用的方法,那么很明显有些地方出了问题。如前所述,通过一个教程将展示如何做到这一点。实际上,在web上搜索使用jdbc执行查询的示例都会显示这一点。
有关其工作原理的额外背景信息,请参阅 execute() 说:
执行此中的sql语句 PreparedStatement 对象,可以是任何类型的sql语句。一些准备好的语句返回多个结果;execute方法处理这些复杂的语句以及这些方法处理的更简单的语句形式 executeQuery 以及 executeUpdate .
execute方法返回一个布尔值来指示第一个结果的形式。必须调用方法 getResultSet 或者 getUpdateCount 检索结果;你必须打电话 getMoreResults 移动到任何后续结果。
的javadoc getMoreResults() 说:
移动到此位置 Statement 对象的下一个结果,如果是 ResultSet 对象,并隐式关闭任何当前 ResultSet 通过该方法获得的对象 getResultSet .
“returnmultipleresults”不是指单个查询中的多行,而是指多个查询中的多个结果。它通常需要执行一个存储过程或一块sql代码才能实现这一点。
这是如何正确地从单个 SELECT 声明:

String qry = "SELECT KIDSNAME FROM TBLKIDS WHERE CID = ?";
try (PreparedStatement ps = connect.prepareStatement(qry)) {
    ps.setInt(1, cid);//setting CID
    try (ResultSet rs = ps.executeQuery()) {
        int i = 0;
        while (rs.next()) {
            out[i] = rs.getString("KIDSNAME");
            i++;
        }
    }
}

如果所讨论的sql代码返回了多个结果集,您可以这样做:

try (PreparedStatement ps = connect.prepareStatement(qry)) {
    // call ps.setXxx() methods here
    boolean isResultSet = ps.execute();
    while (isResultSet) {
        try (ResultSet rs = ps.getResultSet()) {
            int i = 0;
            while (rs.next()) {
                // call rs.getXxx() methods here
                i++;
            }
        }
        isResultSet = ps.getMoreResults();
    }
}

最好是用 for 循环,使循环逻辑保持在一起:

try (PreparedStatement ps = connect.prepareStatement(qry)) {
    // call ps.setXxx() methods here
    for (boolean isResultSet = ps.execute(); isResultSet; isResultSet = ps.getMoreResults()) {
        try (ResultSet rs = ps.getResultSet()) {
            for (int i = 0; rs.next(); i++) {
                // call rs.getXxx() methods here
            }
        }
    }
}
g2ieeal7

g2ieeal72#

这个 getResultSet() 电话不是一个好消息。这个方法对数据库做了一些事情,你不能重复调用它;第一次获得resultset对象(需要关闭)时,第二次重置所有内容。所以不要;您需要调用getresultset()一次。
我怎么知道?通过阅读。直接从 getResultSet() 文档:
每个结果只能调用一次此方法。
此外,这段代码充斥着严重的代码问题,这些问题通常集中在资源上。资源是不只是内存中一堆位的对象,它们代表(并保持打开)一个“资源”。在dbs的情况下,它连接到db引擎。你不能仅仅制造资源,你必须始终把它们放在“保护”块中,以保证资源得到清理。因此,除非没有其他方法,否则您永远不希望它们成为一个字段(这样,它们所属的字段就变成了一个资源)。
那么,事实上你的预处理声明是一个字段?无益。你打电话来的事实。就这样,不设防?无益。
最后,异常处理是愚蠢的。当面对选中的异常时,默认的操作是将它们添加到 throws 条款。如果你做不到,正确的做法是 throw new RuntimeException("uncaught", e); ,不是你做的。 executeQuery 已返回结果集。一般来说,不要打电话 getResultSet *.
最后,数组或多或少是过时的;你想要收藏。
综合起来:

// delete your 'ps' field!

    List<String> getKidsNamebyCid(int cid) throws SQLException {
        var out = new ArrayList<String>();
        String qry = "SELECT KIDSNAME FROM TBLKIDS WHERE CID = ?";
        try (PreparedStatement ps = connect.prepareStatement(qry)) {
            ps.setInt(1, cid);

            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) out.add(rs.getString("KIDSNAME"));
            }
        }
        return out;
    }
  • )preparedstatement api非常不幸。你与ps的互动方式与声明(你应该很少使用;您不能将用户输入添加到纯jane语句中),但因为reasons和history preparedstatement扩展了语句。这意味着一大堆方法都在preparedstatements中,您永远不应该调用它们。那太不幸了。这里有两件事需要学习:[1]java不会破坏向后兼容性,即使这意味着有些API很糟糕,[2]jdbc并不是真正用于“人类消费”的。我们也不会用机器代码来编程我们的CPU,但是机器代码存在并将继续存在。我们使用“机器代码”作为粘合剂;一些库和语言开发人员常用的语言。jdbc也是如此:它不是为你准备的。使用一个具有良好api的库,比如jdbi。这可能超出了你高中课程的要求,但是嘿。没什么好说的,除了:你的课程和老师让你用过时的工具“真正的”**开发人员不使用。
    **)真正意义上的“真实”:是编写代码来驱动那些获得大量金钱和/或眼球的应用程序。

相关问题