如何搜索序列化对象作为数据库查询?

How to search serialized object as a database query?

我正在使用 SQLite 数据库存储对象。为此,我只是将该对象转换为 byte[] 并将其放入数据库中。

但是当我从数据库中检索它时,出现以下错误

无法识别的令牌:“[B@457637e”(代码 1):,编译时:SELECT * 来自 ContentList,其中 subjectNumber=0 AND subjectTypeNumber=0 AND content=[B@ 457637e

为了存储 byte[] 创建了一个包含 BLOB 的列 最初我正在将这个对象搜索到一个空数据库中

byte[] data = SerializationUtils.serialize(Object);
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + 
    DbContract.TABLE_NAME + " WHERE " + DbContract.SUBJECT_NUMBER + "=" + subjectNumber + 
    " AND " + DbContract.SUBJECT_TYPE_NUMBER + "=" + subjectTypeNumber + " AND " + 
    DbContract.CONTENT + "=" + data, null);

您需要将字节数组作为适当的值提供给查询,例如x'ff0099AA'。

例如考虑以下 SQL,其中 DROPS 和 CREATES a table 然后用 BLOBS 插入几行,然后搜索其中一个 blob :-

DROP TABLE IF EXISTS table_with_blob;
CREATE TABLE IF NOT EXISTS table_with_blob (blob_column BLOB);
INSERT INTO table_with_blob VALUES(x'FFFFFFFF'),(x'EEEEEEEE'),(x'DDDDDDDD');
SELECT * FROM table_with_blob WHERE blob_column = x'EEEEEEEE';

如预期的那样,这会导致找到单行:-

  • 命令已注释掉,因此根据工具的工作原理显示结果

  • Blob 不太适合使用,例如,如果您想搜索任何等同于 LIKE x'EE%' 的 BLOBS(请注意,这将不起作用并且会产生在语法错误中)你会做类似的事情:-

    • SELECT *,rowid AS rid FROM table_with_blob WHERE substr(blob_column,1,1) = x'EE';
  • 注意substr函数的开始和长度表示的是字节数而不是十六进制字符串的characters/4bits/nibbles数。

不过,最简单的方法不是编写将字节数组转换为十六进制字符串的方法,而是让查询便捷方法代表您将其转换为十六进制字符串。

所以代替:-

byte[] data = SerializationUtils.serialize(Object);
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + 
    DbContract.TABLE_NAME + " WHERE " + DbContract.SUBJECT_NUMBER + "=" + subjectNumber + 
    " AND " + DbContract.SUBJECT_TYPE_NUMBER + "=" + subjectTypeNumber + " AND " + 
    DbContract.CONTENT + "=" + data, null);

你可以:-

byte[] data = SerializationUtils.serialize(Object);
String whereclause = DbContract.SUBJECT_NUMBER + "=? AND " +
    DbContract.SUBJECT_TYPE_NUMBER + "=? AND " +
    DbContract.CONTENT + "=?";
String[] whereargs = new String[]{subjectNumber,subjectTypeNumber,data}
Cursor = sqLiteDatabase.query(
             DbContract.TABLE_NAME,
             null, //<<<< all columns
             whereclause,
             whereargs,
             null,null,null
);
  • 注意上面的代码是原理代码,没有经过测试,因此可能存在一些错误。
  • 检索内容列的数据时,您需要使用 getBlob 方法,例如mybytearray = getBlob(DbContract.CONTENT);