我正在尝试创建一个命令,我可以向SQLite / Mysql DB发送不同的查询,并将结果集返回给调用的任何函数。它需要能够处理是否有2列或15列。
以下不起作用 - 大概是因为它关闭了结果集/连接,但我不确定如何做到这一点。
思考?
public static ResultSet queryDB(String query) {
try {
Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
resultSet.close();
statement.close();
connection.close();
return resultSet;
} catch (SQLException ex) {
Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
你基本上有3个选择:
ResultSet
,Statement
和Connection
,将这样做的责任交还给来电者。
不推荐,因为它容易出错,并且破坏了格式良好的代码结构范例。Consumer
:
public static void queryDB(String query, Consumer<ResultSet> processor) {
try (
Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
) {
processor.accept(resultSet);
} catch (SQLException ex) {
Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
}
}
然后像这样称呼它:
SQLInterp.queryDB("SELECT * FROM foo", rs -> {
while (rs.next()) {
// process data here
}
});
List<Map<String, Object>>
:
这当然假定查询具有每列的良好唯一名称。
public static List<Map<String, Object>> queryDB2(String query) {
try (
Connection connection = DriverManager.getConnection("jdbc:sqlite:" + Settings.SQLITE_DB_PATH);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
) {
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
String[] name = new String[columnCount];
for (int i = 0; i < columnCount; i++)
name[i] = metaData.getColumnLabel(i + 1);
List<Map<String, Object>> rows = new ArrayList<>();
while (resultSet.next()) {
Map<String, Object> row = new LinkedHashMap<>();
for (int i = 0; i < columnCount; i++)
row.put(name[i], resultSet.getObject(i + 1));
rows.add(row);
}
return rows;
} catch (SQLException ex) {
Logger.getLogger(SQLInterp.class.getName()).log(Level.SEVERE, null, ex);
}
}