繁体   English   中英

Java JDBC将ResultSet存储在ArrayList中

[英]Java JDBC storing ResultSet in ArrayList

我正在尝试自己在Java中使用SQLite数据库。

(我也在使用sqlite-jdbc-3.20.0库 ,但我认为这个问题不受此影响。)

我创建了一些函数,以后将使用它们简化我的工作流程。 为此,我创建了类DBInterface.java ,从它在Main.java类中创建了一个对象。

DBInterface.java的简化内容:

/**
 * Executes a sql String and returns it's results as ResultSet[].
 *
 * @param sql as String holidng the SQL statement to execute
 * @return ResultSet[] containing the results of the query, or empty ResultSet[] if no results
 */
public ArrayList<ResultSet> excecute(String sql)
{
    if(!isConnected()) return null;
    try
    {
        return getResultSets(statement.execute(sql));
    }
    catch (SQLException e)
    {
        Main.log(tag, "An SQLException has occured for statement '"+sql+"':");
        Main.log(tag, e);
    }
    return null;
}

/**
 * Returns an array containing all resultSets of the last executed statement.
 *
 * @param isResultSet as boolean defining if the statement resulted in an result set
 * @return
 */
private ArrayList<ResultSet> getResultSets(boolean isResultSet)
{
    ArrayList<ResultSet> results = new ArrayList<>();

    try
    {
        int count = 0;
        while(true) {
            if(isResultSet)
            {
                ResultSet set = statement.getResultSet();
                results.add(set);
                /*
                while(set.next())
                {
                    //Here the information can still be retrieved
                    Main.log(tag, ""+set.getString("name")+", row:"+set.getRow());
                }
                */

            }
            else
            {
                if(statement.getUpdateCount() == -1)
                {
                    break;
                }

                Main.log(tag, "Result '"+count+"' is just a count: '"+statement.getUpdateCount()+"'");
            }

            count ++;
            isResultSet = statement.getMoreResults();
        }
    }
    catch(SQLException e)
    {
        Main.log(tag, "An SQLException has occured while processing a request:");
        Main.log(tag, e);
    }

    return results;
}

Main.java的简化内容:

public static void main(String[] args)
{
    [...]

    dbInterface.excecute("DROP TABLE IF EXISTS Users");
    dbInterface.excecute("CREATE TABLE IF NOT EXISTS Users (id INTEGER, name STRING(20));");
    dbInterface.excecute("INSERT INTO Users (id, name) VALUES (1, \"Hans\");");
    dbInterface.excecute("INSERT INTO Users (id, name) VALUES (2, \"Peter\");");

    ArrayList<ResultSet> results = dbInterface.excecute("SELECT * FROM Users;");

    log(tag, ""+results.size());
    for(int i = 0; i < results.size(); i++)
    {
        ResultSet set = results.get(i);
        try
        {
            ///*
            while(set.next())
            {
                //TODO Here the information can no longer be retrieved... :(
                Main.log(tag, ""+set.getString("name")+", row:"+set.getRow());
            }
            //*/
        }
        catch (Exception e)
        {
            Main.log(tag, e);
        }
    }
}

根据我的理解,在某些情况下,SQL查询可能会创建多个ResultSet,因此我只是将所有ResultSet对象简单地添加到ArrayList中,这样我就可以知道何时在其他地方处理结果了。 ResultSet存在。 不过,这毫无用处。 通过取消注释DBInterface.javagetResultSets()中的块,我可以确认结果集确实包含该信息。

但是,由于某些原因,我无法从ArrayList在Main.java中执行相同的操作。 我已经测试过更改功能,而是直接返回ResultSet对象,该方法确实起作用,但是它不能实现我的目标,因为我想返回所有可能的ResultSet objetcs,而不仅仅是一个。

您可以编写一种将ResultSet转换为列表,映射或类并将ResultSet的结果存储在对象中的方法

像这样

public List resultSetToArrayList(ResultSet rs) throws SQLException {
    ResultSetMetaData md = rs.getMetaData();
    int columns = md.getColumnCount();
    List<Map<String, Object>> list = new ArrayList<>();
    while (rs.next()) {
        Map<String, Object> row = new HashMap<>(columns);
        for (int i = 1; i <= columns; ++i) {
            row.put(md.getColumnName(i), rs.getObject(i));
        }
        list.add(row);
    }

    return list;
}

切记在不使用时关闭ResultSet,Statement和Connection

关闭ResultSet显式地使垃圾回收器有机会尽早重新收集内存,因为ResultSet对象可能会占用大量内存,具体取决于查询。

当然,使用Spring会容易得多,但是最好知道如何使用普通的旧JDBC。

创建一个Java类来保存结果对象并返回列表中的对象,而不是返回List对象。

您可以使用专门用于返回这些对象的方法来执行此操作。

例如,如果创建了User类,则可以执行以下操作:

private static String SQL = "SELECT * FROM Users";
...

private List<User> getUsers()
{
    List<User> results = new ArrayList<>();

    try
    {
        PreparedStatement statement = connection.prepareStatement(SQL);
        ResultSet rs = statement.executeQuery(SQL);
        while(rs.next()) {
          User aUser = new User();
           aUser.setUserid(rs.getString("USER_ID"));
           aUser.setUserName(rs.getString("USERNAME"));
           ...
         results.add(aUser);
        }
    }
    catch(SQLException e) {
     // log any exceptions ...
    }
    finally() {
     // always close your JDBC resources - google it
     // example
     try{
        if (statement != null) {
           statement.close();
           statement=null;
        }
      }
      catch(SQLException e) {
        // couldn't close statement
      }
      ...
    }

    return results;
}

如果您没有使用JDBC DataSource ,那么您必须自己管理数据库连接-这可能很繁琐,并且是应用程序错误的常见来源。 几乎所有现代Java应用程序都使用DataSource实现(并且池化DataSource非常普遍)而不是简单的JDBC连接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM