使用JPA将UUID以字符串形式存储在MySQL中

19

我在阅读一篇关于如何在Hibernate和MySql中使用UUID的博客时发现一个问题。现在的问题是,每当我查看数据库时,ID都将以不可读的格式(二进制-16)显示。如何将UUID存储为可读格式,例如7feb24af-fc38-44de-bc38-04defc3804fe而非¡7ôáßEN¹º}ÅÑs

我正在使用以下代码:

@Id
@GeneratedValue( generator = "uuid2" )
@GenericGenerator( name = "uuid2", strategy = "uuid2" )
@Column( name = "id", columnDefinition = "BINARY(16)" )
private UUID id;

结果是 ¡7ôáßEN¹º}ÅÑs。但我想要一个可读的UUID,所以我使用了以下代码,但没有帮助我

@Id
@GeneratedValue( generator = "uuid2" )
@GenericGenerator( name = "uuid2", strategy = "uuid2" )
@Column( name = "id", columnDefinition = "CHAR(32)" )
private UUID id;

如何将 UUID 保存为字符串而不改变 Java 类型 UUID 的类型为二进制(16)?


1
想一想...使用二进制(16)的UUID对性能更好。 - Raymond Nijland
你从控制台或任何GUI工具中得到了结果¡7ôáßEN¹º}ÅÑs吗? - dkb
6
为什么要以低效的格式保存它?当你需要查看表格时,只需使用 BIN_TO_UUID(id) 即可。 - RealSkeptic
BIN_TO_UUID(id) 只能在 MySQL 8.0 中使用 @RealSkeptic - Raymond Nijland
1
是的,我同意,但是有没有一种方法只在表格中用字符串表示UUID,并将其作为Java中的UUID对象使用?如果您使用MySQL 5.7+,则可以使用生成的列从二进制ID列生成可读的UUID -> https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html。如果没有MySQL 5.7+,则可以使用基本视图。 - Raymond Nijland
显示剩余3条评论
4个回答

52

只需使用@org.hibernate.annotations.Type(type="uuid-char")

数据类型有三个层级:
- Java类型
- Hibernate类型
- 数据库特定类型。

Hibernate数据类型表示是Java数据类型和数据库类型之间的桥梁,使其独立于数据库。

您可以检查这个映射。正如您可以在那里找到的那样,java.util.UUID可映射到不同类型(二进制或char / varchar)。uuid-binary是Hibernate的UUIDBinaryType的关键,您默认获得此类型,并将其映射到您的数据库的BINARY

如果要在UUID下获取CHAR类型,则应向Hibernate说明要使用其UUIDCharType。为此,您使用 uuid-char 键,并且正如您可以在@Type注释的JavaDoc中检查到的那样:定义了Hibernate类型映射。因此,您使用注释来解释hibernate应使用哪个桥接器。


你能稍微解释一下你的答案吗? - ficuscr
1
@ficuscr 我已经添加了解释。 - Ivan Osipov

7

@Type注解已被弃用,并且在Spring Boot的最新版本中甚至不存在。

现在您需要使用@JdbcTypeCode

正确的做法如下:

@Column(columnDefinition = "VARCHAR(36)")
@JdbcTypeCode(SqlTypes.VARCHAR)

这应该放在顶部。适用于Spring Boot 3。 - Shah Erhan

4

在我的上一个项目中(spring-boot:2.5.3+mariaDB)也遇到了相同的问题。
所以我添加了以下注释 @Type(type = "org.hibernate.type.UUIDCharType") 来解决它。

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.util.UUID;
/** imports */

@Entity()
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @Column(name = "uuid", columnDefinition = "char(36)")
    @Type(type = "org.hibernate.type.UUIDCharType")
    private UUID uuid;

   /** ... */
}

hibernate注解 @Type 的目的是定义数据库中存储的数据类型,并且与前面的一行 @Column(name = "uuid", columnDefinition = "char(36)") 兼容。

在搜索过程中,我注意到mariaDB和MySQL有相同的问题。

您可以在此处查看更多不同用例中使用org.hibernate.annotations.Type的示例。


0

我正在使用这些注解:

@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2r")
@Column(name = "id", columnDefinition = "varchar(36)")
@Type(type = "uuid-char")
private UUID uuid;

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接