无法从Java中的ResultSet加载对象

时间:2018-03-24 20:10:09

标签: java sqlite

我在从SQLite数据库加载对象时遇到问题。

首先,这是我的表定义:

CREATE TABLE MyTable (
  rowid INTEGER PRIMARY KEY,
  data BLOB
);

这是我想要存储和重新加载的简单类:

public class MyHashMap extends HashMap<String, Integer> {
    private static final long serialVersionUID = 0L;
}

然后我用一些数据填充地图并将其与数据库中的SQL INSERT语句一起存储。一切正常,如果我执行SELECT(使用sqlite3命令行客户端),我将看到正确的信息。

现在我正在使用java.sql包来加载对象:

String sql = "SELECT data FROM MyTable WHERE rowid = 1";
MyHashMap map = null;

try {
  try (Statement stmt = db.createStatement()) {
    try (ResultSet rs = stmt.executeQuery(sql)) {
      if (rs.next()) {
        map = rs.getObject("data", MyHashMap.class);
      }
    }
  }
} catch (Exception e) {
  e.printStackTrace();
}

没有抛出异常,但我的map变量为null。我调试了程序,我可以说getObject方法是按预期调用的。

2 个答案:

答案 0 :(得分:0)

首先,您对MyHashMap的定义不正确

public class MyHashMap extends HashMap<Integer, String> {
    private static final long serialVersionUID = 0L;
}

但主要问题是SQL不存储Java对象;它只存储由字段组成的记录行。您需要逐个阅读这些记录,并将它们存储在地图中。大致如下:

MyHashMap map = new MyHashMap();
final String sql = "SELECT rowid, data FROM MyTable";
try (final Statement stmt = connection.createStatement;
        final ResultSet rs = stmt.executeQuery(sql)) {
    while (rs.next()) {
        map.put(rs.getInt(1), rs.getString(2));
    }
 }

请注意,将Blob读入String的机会很有可能会失败。通常,JDBC驱动程序足够聪明地转换数据类型,但如果blob中有原始二进制数据,则无法将其读入字符串。您需要使用getBlob方法,并处理生成的对象。但我无法从你的代码中知道你将在那个blob中存储什么。

答案 1 :(得分:0)

好的,我找到了一个使用以下方法的解决方案:

private Object getObjectFromBlob(ResultSet rs, String columnName)
    throws ClassNotFoundException, IOException, SQLException {
  InputStream binaryInput = rs.getBinaryStream(columnName);
  if (binaryInput == null || binaryInput.available() == 0) {
    return null;
  }

  ObjectInputStream in = new ObjectInputStream(binaryInput);
  try {
    return in.readObject();
  } finally {
    in.close();
  }
}