简体   繁体   English

无法从Java的ResultSet中加载对象

[英]Can't load objects from a ResultSet in Java

I have a problem with loading objects from a SQLite database. 我从SQLite数据库加载对象时遇到问题。

First of all, this is my table definition: 首先,这是我的表定义:

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

This is the simple class which I want to store and reload: 这是我要存储和重新加载的简单类:

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

Then I'm filling the map with some data and store it with an SQL INSERT statement in the database. 然后,我用一些数据填充地图,并使用SQL INSERT语句将其存储在数据库中。 Everything works fine and if I execute a SELECT (with the sqlite3 command-line client) I will see the correct information. 一切正常,如果执行SELECT(使用sqlite3命令行客户端),我将看到正确的信息。

Now I'm using the java.sql package to load the object: 现在,我正在使用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();
}

There's no exception thrown but my map variable is null. 没有引发异常,但我的map变量为null。 I debugged the program and I can say that the getObject method is called as expected. 我调试了程序,可以说getObject方法被调用了。

First, you definition of MyHashMap is incorrect 首先,您对MyHashMap定义不正确

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

The main issue, though, is that SQL doesn't store Java objects; 不过,主要问题是SQL不存储Java对象。 it merely stores rows of records, which consist of fields. 它仅存储由行组成的记录行。 You need to read these records one by one, and store them in your map. 您需要一一读取这些记录,并将其存储在地图中。 Roughly as follows: 大致如下:

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));
    }
 }

Please note that there's a good chance that reading a Blob into a String will fail. 请注意,很有可能将Blob读取为String会失败。 Usually, JDBC drivers are clever enough to convert data types, but if you have raw binary data in your blob, you cannot read it into a string. 通常,JDBC驱动程序足够聪明,可以转换数据类型,但是如果您的blob中有原始二进制数据,则无法将其读取为字符串。 You would need the getBlob method instead, and deal with the resulting object. 您将需要getBlob方法来代替,并处理结果对象。 But I can't tell from your code what you'll be storing in that blob. 但是我无法从您的代码中得知您将在该blob中存储什么。

Ok, I found a solution with the following method: 好的,我找到了使用以下方法的解决方案:

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();
  }
}

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

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