Android 如何在Room数据库中存储Protobuf Java模型?

Android 如何在Room数据库中存储Protobuf Java模型?,android,android-room,Android,Android Room,是否可以将生成的Protobuf Java类中的对象存储在房间数据库中?我是否需要序列化对象并将序列化版本存储在实体类中?基本上有两个选项。序列化并另存为Blob(字节[]),或拥有反映对象属性的实体,如果这些实体本身就是对象,则按wise将其分解。后一种方法可能更复杂,但它确实使数据在数据库方面变得更有用 简言之,序列化或不序列化是一个取决于所需内容的选择。您只是想将数据库用于存储,还是想利用SQLite(Room)提供的可搜索性 例如,假设您有一个地址的合同,该地址具有以下属性:- 邮箱(

是否可以将生成的Protobuf Java类中的对象存储在房间数据库中?我是否需要序列化对象并将序列化版本存储在实体类中?

基本上有两个选项。序列化并另存为Blob(字节[]),或拥有反映对象属性的实体,如果这些实体本身就是对象,则按wise将其分解。后一种方法可能更复杂,但它确实使数据在数据库方面变得更有用

简言之,序列化或不序列化是一个取决于所需内容的选择。您只是想将数据库用于存储,还是想利用SQLite(Room)提供的可搜索性

例如,假设您有一个地址的合同,该地址具有以下属性:-

  • 邮箱(内部)
  • 街(串)
  • 城市(字符串)
  • 国家(字符串或更准确地说是对国家对象的引用)
然后,如果序列化对象,则会有一个字节字符串(字节[]),所有数据都将存储在一列中

如果你想搜索一个城市里的所有地址,那将是一种效率低下且相对困难的做法

如果每个属性都保存在一个表中,每个属性都有一列,那么搜索城市是很简单的,例如,
从_表中选择您的_列,其中city='MyCity'

如果地址对象被序列化并保存,您可能会幸运地使用
从instr(serialized_address,hex('MyCity')>0;

  • 这取决于序列化如何生成底层数据
房间下面是SQLite,下面是一个快速的SQLite示例,演示了假设属性标记是属性名称(例如city)后跟=例如city MyCity存储为city=MyCity转换为十六进制(字节)时的区别

  • 这将创建2个表(房间中的实体)

  • 表test1用于序列化对象地址

  • 表test2将属性存储在各个列中

  • 两个表都加载了等效的数据

  • 第一个查询使用null从两个表中获取test1表中不存在的3列的数据

    • i、 e.所有数据都存储在单个列中
  • 第二个查询查找名为MyCity的城市,希望仅提取该1个城市

运行时,结果为:-

(即每个表中有2行)

以及:-

如您所见,已提取了3行,而不是预期的2行。这是因为通过MyCity的字节数组搜索也找到了NotMyCity

DROP TABLE IF EXISTS test1;
CREATE TABLE IF NOT EXISTS test1 (serialised_address BLOB);
CREATE TABLE IF NOT EXISTS test2 (postbox INTEGER, street TEXT, city TEXT, country TEXT);

INSERT INTO test1 
    VALUES(hex('postbox=1,street="The Street",city="MyCity",country="England"')),
    (hex('postbox=1,street="The Street",city="NotMyCity",country="England"'))
    ;
INSERT INTO test2 VALUES(1,'The Street','MyCity','England'),(1,'The Street','NotMyCity','England');

SELECT *,null,null,null FROM test1 UNION SELECT * FROM test2;

SELECT 'S1',serialised_address,null,null,null FROM test1 WHERE instr(serialised_address,hex('MyCity')) > 0
UNION SELECT 'S2',serialised_address,null,null,null FROM test1 WHERE instr(serialised_address,hex('myCity')) > 0
UNION SELECT 'S3',* FROM test2 WHERE city = 'MyCity'
UNION SELECT 'S4',* FROM test2 WHERE city = 'mycity'
;