我在从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方法是按预期调用的。
答案 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();
}
}