【问题标题】:Which MySQL type do I need to store both regular Strings and hash values?我需要哪种 MySQL 类型来存储常规字符串和哈希值?
【发布时间】:2015-07-28 14:01:11
【问题描述】:

我正在使用额外的实体/表 Event 记录我的 JPA 实体上的更改:

@Entity
public class Event {

  private String fieldName;

  @Lob
  @Column
  private String previousValue;

  @Lob
  @Column
  private String newValue;

  // ...
}

现在,我正在查看的字段可以有多种类型。如果它们已经不是字符串,而是 @ManyToMany 集合,我将在保存之前构建有用的字符串表示 - 这很好。

唯一的问题是我的User 实体,它有一个字段byte[] passwordHash。在 MySQL 表中,它存储为 tinyblob 并且也可以正常工作。 不起作用的工作是将EventnewValue = new String(passwordHash, StandardCharsets.UTF_8) 保持一致。它显然变得乱码,我收到以下错误:

Hibernate: insert into DbEvent (timestamp, fieldName, modelId, modelName, newValue, previousValue) values (?, ?, ?, ?, ?, ?)
15:38:25,466 TRACE BasicBinder:81 - binding parameter [1] as [TIMESTAMP] - [Tue Jul 28 15:38:25 CEST 2015]
15:38:25,466 TRACE BasicBinder:81 - binding parameter [2] as [VARCHAR] - [passwordHash]
15:38:25,466 TRACE BasicBinder:81 - binding parameter [3] as [BIGINT] - [17]
15:38:25,467 TRACE BasicBinder:81 - binding parameter [4] as [VARCHAR] - [User]
15:38:25,467 TRACE BasicBinder:81 - binding parameter [5] as [CLOB] - [G�S�G��M��j�I��
F/�-]
15:38:25,467 TRACE BasicBinder:69 - binding parameter [6] as [CLOB] - [null]
15:38:25,468  WARN SqlExceptionHelper:144 - SQL Error: 1366, SQLState: 22001
15:38:25,468 ERROR SqlExceptionHelper:146 - Data truncation: Incorrect string value: '\xEF\xBF\xBD\x17S\xEF...' for column 'newValue' at row 1

所以我的问题是:

我需要哪些注释或类型才能使其工作?你看我已经尝试过@Lob(MySQL 类型longtext),因为我首先认为该值太长,但它没有帮助。我猜它与字符编码有关。我如何让 MySQL 不关心这个?我可以/应该简单地将EventString 字段更改为byte[]

有没有什么办法可以做到这一点?

如果我的情况不清楚或者您需要更多信息来解决这个问题,请告诉我。我希望有人可以帮助我:)

提前致谢!


[更新]

好的,所以将Event 更改为存储private byte[] previousValueprivate byte[] newValue 似乎就足够了。有什么反对意见吗?

另外,MySQL 的输出现在看起来有点搞砸了:

+----+---------------------+--------------+---------------+----------------------------------------------+
| id | timestamp           | fieldName    | previousValue | newValue                                     |
+----+---------------------+--------------+---------------+----------------------------------------------+
| 16 | 2015-07-28 16:19:34 | passwordHash | NULL          | 6��?�%4�
��                      |                                          aJ��e�[�½
+----+---------------------+--------------+---------------+----------------------------------------------+

可能无法治愈?

【问题讨论】:

  • 如果你想将 arbitrary byte[] 存储为String,你不应该使用UTF-8,因为这会拒绝许多字节组合 - 而你应该使用@ 987654342@ 可让您将任何字节数组转换为 String ,反之亦然。

标签: mysql hibernate jpa annotations bytearray


【解决方案1】:

将它们保存为字符串。我推荐使用 Base 64 编码方式,例如:

import org.apache.commons.codec.binary.Base64;
...
public static byte[] base64ToByte(String data) {
    Base64 decoder = new Base64();
    return decoder.decode(data);
}

public static String byteToBase64(byte[] data) {
    Base64 endecoder = new Base64();
    return endecoder.encodeToString(data);
}
...

当我需要保存哈希时,我总是使用这些方法,当您保存哈希时,将它们编码为 Base64 以及当您需要比较哈希,然后解码为字节数组时,因为最佳实践要求您必须比较字节级别的哈希。

Base64 类是 commons-codec-[version].jar 的一部分,我有 1.10 版本,但我分享了你可以找到它的链接,也许有更新的版本。

http://mvnrepository.com/artifact/commons-codec/commons-codec

希望这些信息对您有所帮助。

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 2018-09-23
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多