【问题标题】:How to return the Result Set in Java如何在 Java 中返回结果集
【发布时间】:2019-04-02 17:48:48
【问题描述】:

我正在尝试返回给定学生 ID 的结果集并显示 gpa。但是,当结果集关闭时,我无法执行该操作。这是我的代码:

/**
 * Returns a ResultSet with a row containing the computed GPA (named as gpa) for a given student id.
 * You must use a PreparedStatement.
 * 
 * @return
 *       ResultSet containing computed GPA
 */
public ResultSet computeGPA(String studentId) throws SQLException
{
    ResultSet rst;

     // TODO: Use a PreparedStatement
    try(Connection con = connect()){

        String sql = "SELECT gpa FROM student WHERE sid=?";
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, studentId);
        rst = pstmt.executeQuery();

        while(rst.next()){
            System.out.println(rst.getString("gpa"));
        }
    }
    return rst;
}

这是我得到的结果

连接到数据库。 2.96 线程“main”java.sql.SQLException 中的异常:在 ResultSet 关闭后不允许操作 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975) 在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920) 在 com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:804) 在 com.mysql.jdbc.ResultSetImpl.getMetaData(ResultSetImpl.java:3107) 在 EnrollJDBC.resultSetToString(EnrollJDBC.java:500) 在 EnrollJDBC.main(EnrollJDBC.java:59)

【问题讨论】:

    标签: java mysql database resultset


    【解决方案1】:

    当你的try 块完成时,你使用try-with-resources 关闭Connection。在 Java 中,当您关闭 Connection 时,您也会自动关闭与该连接关联的所有 ResultSet 对象。这就是异常告诉你的。您正在尝试使用封闭的ResultSet。因此,只有在 ResultSet 被完全处理后,您才需要更改代码以关闭连接。

    由于您通过 id 执行SELECT,您会得到一条记录或没有记录。那么,为什么不只返回该值(如果存在)或 null(或空字符串),如果具有此类 id 的学生不存在,而不是从 computeGPA() 方法返回 ResultSet 对象?

    【讨论】:

      【解决方案2】:

      当(准备好的)语句被关闭时,它的结果集也被关闭。 这是可以理解的,因为 ResultSet 是一个沉重的类,包含元数据和所有内容。

      返回更具体的列表。

      public List<String> computeGPA(String studentId) throws SQLException {
          String sql = "SELECT gpa FROM student WHERE sid=?";
          try (Connection con = connect();
                  PreparedStatement pstmt = con.prepareStatement(sql)) {
              pstmt.setString(1, studentId);
              try (ResultSet rst = pstmt.executeQuery()) {
                  List<String> gpas = new ArrayList<>();
                  while (rst.next()) {
                      gpas.add(rst.getString(1));
                  }
                  return gpas;
              }
          }
      }
      

      正如所说,官方不需要第二个 try-with-resources,但代码检查器会注意到 ResultSet 是可自动关闭的,并且可能会给出误报警告。

      【讨论】:

      • 好吧,如果行不是字符串而是不同类型的行怎么办?
      • @Freddy 我使用了 OP 的类型,错误 Operation not allowed after ResultSet closed 表明它们可能没问题。 setLong(1, longId) 其他情况。
      【解决方案3】:

      你不能返回 ResultSet 因为它会在方法被销毁时关闭。但是你可以从 ResultSet 中获取原始数据,试试这个:

      public ArrayList<Byte[]> getResultQuery(String query){
          ArrayList<Byte[]> arrayList = new ArrayList<>();
          Byte[] row;
          conn = getConnection(db_url);
          try {
              Statement statement = conn.createStatement();
              ResultSet resultSet = statement.executeQuery(query);
              int countColumn = resultSet.getMetaData().getColumnCount();
              if (countColumn==0) return null;
              while (resultSet.next()){
                  row = new Byte[countColumn];
                  for (int i = 0; i<countColumn; i++){
                      row[i] = resultSet.getByte(i+1);
                  }
                  arrayList.add(row);
              }
          } catch (SQLException e) {
              e.printStackTrace();
          }
          return arrayList;
      }
      
      public static Connection getConnection (String db_url){
          Connection conn = null;
          try{
              Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
              conn = DriverManager.getConnection(db_url);
          }catch(Exception e){
              e.printStackTrace();
          }
          return conn;
      }
      

      在此,我尝试在 ResultSet 中返回 Byte[]、1 Byte[] = 1 行的 ArrayList。如果您想获得一些价值,只需将 Byte[i] 转换为您想要的数据类型!

      【讨论】:

        猜你喜欢
        • 2020-08-16
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-23
        • 2021-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多