【问题标题】:Persist a Java instance of an Interface in a database在数据库中持久化接口的 Java 实例
【发布时间】:2015-11-06 21:53:22
【问题描述】:

我想在关系数据库 (PostgreSQL) 中持久化一个对象。我不知道要持久化的对象的具体类,只知道它实现了一个接口。

最好的方法是什么?

我正在考虑做类似的事情:

Interface obj = new InterfaceImpl();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(buffer);
oos.writeObject(obj);
oos.close();
byte[] rawData = buffer.toByteArray();

String base64String = Base64.encodeBase64String(bytes);
//Persist the string to DB


//Load string from db
byte[] backToBytes = Base64.decodeBase64(base64String);
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
Interface obj = (Interface) is.readObject();

有更好的解决方案吗?

【问题讨论】:

  • 如果您对对象的类型及其真正的实现一无所知,那么像您正在做的基本 Java 序列化可能是您能做的最好的事情。
  • 也许 bytea 数据类型而不是文本(我猜你将使用 base64 编码建议)对你来说是更好的解决方案。请参阅postgresql.org/docs/9.1/static/datatype-binary.html 了解更多信息。

标签: java postgresql serialization persistence


【解决方案1】:

如果这就是您对该对象的全部了解,那么您真正能做的就是将其存储在 bytea 字段中,并在以后需要时再次检索它。

使用bytea 而不是text。与text不同,它对于二进制数据(不支持排序规则或自然语言)更快,并且支持存储零(null)字节。

这应该是在数据库中存储数据的绝对最后手段。它总是导致痛苦。有人会过来问“好的,现在写一个查询,在那里你可以找到所有类型为com.mycompany.Apple 的对象,它们的colour 属性设置为"red"。你必须回复“对不起,我不能这样做,数据库只是看到一堆二进制乱码”。你会被告知“无论如何都要做”。所以你从数据库中读取每个对象,反序列化它,检查它类型,通过反射检查其属性并丢弃它或根据结果保留它。数据库变得越来越大,这变得越来越慢。因此,您开始添加列以缓存有关数据库中对象的信息,但随后它们开始流出与存储的数据同步,因为某些代码忘记更新它们...

我之前编写过在bytea 字符串中查找的查询,用于手动反序列化和检查部分Java 对象。可怕的东西。不推荐。

如果可以,请使用更实用的对象结构序列化,例如json。当您不可避免地被要求这样做时,您可以以实用的方式从数据库中查询。

【讨论】:

  • 我可以得到在运行时已知的实现接口的对象的类,并将其添加到另一列。你怎么看?
  • @mat_boy 仍然很糟糕——这应该是你最后的手段。但它会起作用。
猜你喜欢
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多