返回

Hibernate 6.4 原生查询读取 JSONB:轻松转换为 ArrayList

java

从 Hibernate 6.4 原生查询中读取 JSONB

在使用 Hibernate 6.4 和 PostgresQL 处理 JSONB 列时,你会发现从原生查询读取的数据会被转换为 String,而不是期望的 ArrayList。为了解决这个问题,让我们深入了解如何在 Hibernate 6.4 中使用 ResultSetMapping 将 JSONB 列转换为 ArrayList。

使用 ResultSetMapping

ResultSetMapping 允许我们指定原生查询结果映射到实体的方式。它为我们提供了控制从原生查询中读取的列类型和将它们转换为所需格式的能力。

要使用 ResultSetMapping 转换 JSONB 列为 ArrayList,请执行以下步骤:

  1. 创建 ResultSetMapping: 使用 @ResultSetMapping 注解创建一个 ResultSetMapping。该注解指定了 ResultSetMapping 的名称和它映射到的实体。
@ResultSetMapping(name = "JsonMapping", classes = { MyEntity.class })
  1. 指定列映射: 使用 @ConstructorResult@ColumnResult 注解指定列映射。@ConstructorResult 确定将从 ResultSet 中映射到实体的属性,而 @ColumnResult 则指定列名和目标类型。
@ConstructorResult(
    targetClass = MyEntity.class,
    columns = {
        @ColumnResult(name = "data", type = Class.class),
        @ColumnResult(name = "id", type = Integer.class)
    }
)
  1. 使用 ResultSetMapping 进行原生查询: 使用 createNativeQuery() 方法进行原生查询并指定 ResultSetMapping 名称作为第二个参数。
var rows = session.createNativeQuery("SELECT CAST('[1,2,3]' as jsonb) as data, 2 as id", "JsonMapping").list();

好处

使用 ResultSetMapping 转换 JSONB 列为 ArrayList 具有以下好处:

  • 控制从原生查询中读取的列类型。
  • 将 JSONB 列直接映射到实体的 ArrayList 属性。
  • 避免手动转换数据类型。

其他注意事项

  • 确保你的实体中有与 JSONB 列对应的 ArrayList 属性。
  • 启用延迟加载 (hibernate.enable_lazy_load_no_trans) 以确保在使用原生查询时加载实体。

示例代码

https://github.com/chadselph/hibernate-json-native-query

常见问题解答

  1. 为什么默认情况下 Hibernate 6.4 将 JSONB 转换为 String? Hibernate 默认使用 Jackson 转换器,它将 JSONB 转换为 String。
  2. 我是否可以在没有 ResultSetMapping 的情况下将 JSONB 转换为 ArrayList? 不,ResultSetMapping 是转换 JSONB 列为 ArrayList 的唯一方法。
  3. 是否可以在映射到实体的字段上使用 ResultSetMapping? 是,可以使用 ResultSetMapping 将原生查询结果映射到实体的任何字段。
  4. 我可以在原生查询中使用多个 ResultSetMapping 吗? 是,可以在一个原生查询中使用多个 ResultSetMapping。
  5. ResultSetMapping 可以用于映射复杂的类型吗? 是,ResultSetMapping 可以用于映射任何复杂的类型,包括嵌入式对象和集合。

结论

通过使用 ResultSetMapping,你可以轻松地将 JSONB 列从 Hibernate 6.4 原生查询转换为 ArrayList。这提供了灵活性和控制,确保从原生查询中获取数据符合你的应用程序需求。通过遵循本文中概述的步骤,你可以有效地管理你的 JSONB 列,将其转换为所需的格式。