【问题标题】:Java SQL what is the best way to save class with HashMap attribute in MySQL databaseJava SQL在MySQL数据库中保存具有HashMap属性的类的最佳方法是什么
【发布时间】:2014-04-08 10:53:06
【问题描述】:

我不知道在数据库中保存 HashMap 的最佳方法是什么(HashMap 可能非常大)所以我的第一个想法是将 HashMap 保存为 blob(在一列中),另一个想法是保存 HashMap 中与键对应的每个值,但我认为这会使它变大。

我的示例类:

public class MyObject {
    private int id;
    private HashMap<Integer, CustomHash> hashes;
    // getters and setters
}

我还听说过序列化类并将其保存在数据库中。有什么建议吗?

也没有使用ORM,只有普通的JDBC

编辑:如何将 hashmap 保存到 clob 中?

CREATE TABLE IF NOT EXISTS myobjects (
   id int GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
   hashes clob NOT NULL
);

我的声明:

PreparedStatement ps = null;
try {
    ps = this.connection.prepareStatement("INSERT INTO myobjects (hashes) VALUES (?)");
    ps.setClob(1, (Clob) myObject.getHashes());
    ps.executeUpdate();
} catch(SQLException sqlEx) {
    sqlEx.printStackTrace();
} finally {
    DAOUtility.close(this.connection, ps);
}

错误:HashMap 无法转换为 Clob

【问题讨论】:

  • 你看过 JPA 吗?
  • 您想要一个包含三列的表 - id 字段的整数,地图键的整数和地图的 varchar(或者可能是某种 CLOB/文本列)值。
  • 我宁愿不单独存储地图的键和值。
  • 将它们放在数据库表同一行的不同列中很难“分开”。做任何其他事情只是意味着您以后必须以某种方式将它们分开。

标签: java sql hashmap


【解决方案1】:

免责声明:这不是最佳方式,而是将地图实例保存在 rdbms 中的众多方式之一。

CLOB 用于大型字符对象(通常高达 2 或 4 GB)。我在上面建议它,因为您提到使用 JSON 来序列化您的地图。好的,这是一个简单的可能性(使用 BLOB):

CREATE TABLE IF NOT EXISTS myobjects (
   id int GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
   hashes blob(32K) NOT NULL
);

并使用您的 sn-p 进行插入:

PreparedStatement ps = null;
try {
    // serialize your map
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    ObjectOutputStream output = new ObjectOutputStream(b);
    o.writeObject(myObject().getHashes());

    ps = this.connection.prepareStatement("INSERT INTO myobjects (hashes) VALUES (?)");
    ps.setBinaryStream(1, new ByteArrayInputStream(b.toByteArray()));
    ps.executeUpdate();
} catch(IOException ioEx) {
    ioEx.printStackTrace();
} catch(SQLException sqlEx) {
    sqlEx.printStackTrace();
} finally {
    DAOUtility.close(this.connection, ps);
}

请注意,您的值也需要可序列化。

不过,这仅允许您在 JVM 上使用您的持久化映射。如果您打算直接在数据库中访问地图,我强烈建议将地图“映射”到三列(id、key、value)。这将更加透明,但需要更多的工作(即更多的 SQL 查询)来存储/检索地图。高温

【讨论】:

  • @T0tec:明白我的意思了吗?此外,对于其他解决方案,请查看,例如。 stackoverflow.com/questions/5776331/…
  • 是的,我知道这不是描述的好方法,但我会接受你的回答。
  • 另外,请注意还有其他库可以使用字符串而不是字节数组。出于多种原因,这可能很有用。此外,如果您使用 Java 的直接序列化,请确保您的 CustomHash 类定义了 private static final long serialVersionUID = some random long number; 否则,即使您的类定义发生轻微变化,反序列化也会遇到麻烦。请参考章节。 J. Bloch 的 Effective Java 中的 11 篇,用于良好实践。 HTH
猜你喜欢
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 2020-04-08
  • 2014-08-04
  • 2021-04-21
  • 2010-10-16
  • 1970-01-01
相关资源
最近更新 更多