如何使用 Helidon 2.0.0-M-2 更改查询返回的 JSON
How to change JSON returned by query using Helidon 2.0.0-M-2
我正在使用 Helidon 2.0.0-M2。
当我 运行 下面的查询时,我得到了 JSON 个对象的列表。
dbClient.execute(exec -> exec.createNamedQuery("select-dsitem-by-id")
.addParam("userId", dataItemId)
.execute())
.thenAccept(response::send)
.exceptionally(throwable -> sendError(throwable, response));
返回列表
[
{
"data": "qwerty",
"user_id": "12345"
},
{
"data": "qwerty123",
"user_id": "22345"
}
]
属性名称似乎直接取自数据库列名称。例如返回的一个属性名称是 "user_id"。但是,我希望它是 "userId"。我还想为此列表创建一个父包装器,例如:
{
"userList": [
{
"data": "qwerty",
"user_id": "12345"
},
{
"data": "qwerty123",
"user_id": "22345"
}
]
}
使用 dbclient 执行此操作的最佳方法是什么?
谢谢
简单的方法:
将您的 SQL 语句更改为 return 正确的名称,例如:
SELECT data, user_id as userId FROM mytable
复杂的方法:
我们正在致力于更好地支持映射到 JSON 流。
目前只有一种(有点复杂)的方法可以实现:
您可以创建从 DbRow
到 JsonObject
的自定义映射器。此映射器需要是通用映射器(它必须适用于任何查询的任何 DbRow
)。
内置映射器使用列上提供的元数据。我准备了一个简单的例子(只希望有单一类型的语句):
class DbRecordMapperProvider implements DbMapperProvider {
private static final DbMapper<JsonObject> MAPPER = new DbRecordMapper();
@SuppressWarnings("unchecked")
@Override
public <T> Optional<DbMapper<T>> mapper(Class<T> aClass) {
if (JsonObject.class.equals(aClass)) {
return Optional.of((DbMapper<T>)MAPPER);
}
return Optional.empty();
}
}
class DbRecordMapper implements DbMapper<JsonObject> {
@Override
public JsonObject read(DbRow dbRow) {
return Json.createObjectBuilder()
.add("name", dbRow.column("FIRSTPART").as(String.class))
.add("message", dbRow.column("SECONDPART").as(String.class))
.build();
}
@Override
public Map<String, ?> toNamedParameters(JsonObject dbRecord) {
return dbRecord;
}
@Override
public List<?> toIndexedParameters(JsonObject dbRecord) {
throw new IllegalStateException("Cannot convert json object to indexed parameters");
}
}
重要的方法是public JsonObject read(DbRow dbRow)
。
一旦有了这样的 DbMapperProvider
,就可以在 DbClient 中注册它:
dbClient = DbClient.builder()
.config(config.get("db"))
.mapperProvider(new DbRecordMapperProvider())
.build();
我正在使用 Helidon 2.0.0-M2。 当我 运行 下面的查询时,我得到了 JSON 个对象的列表。
dbClient.execute(exec -> exec.createNamedQuery("select-dsitem-by-id")
.addParam("userId", dataItemId)
.execute())
.thenAccept(response::send)
.exceptionally(throwable -> sendError(throwable, response));
返回列表
[
{
"data": "qwerty",
"user_id": "12345"
},
{
"data": "qwerty123",
"user_id": "22345"
}
]
属性名称似乎直接取自数据库列名称。例如返回的一个属性名称是 "user_id"。但是,我希望它是 "userId"。我还想为此列表创建一个父包装器,例如:
{
"userList": [
{
"data": "qwerty",
"user_id": "12345"
},
{
"data": "qwerty123",
"user_id": "22345"
}
]
}
使用 dbclient 执行此操作的最佳方法是什么?
谢谢
简单的方法:
将您的 SQL 语句更改为 return 正确的名称,例如:
SELECT data, user_id as userId FROM mytable
复杂的方法: 我们正在致力于更好地支持映射到 JSON 流。 目前只有一种(有点复杂)的方法可以实现:
您可以创建从 DbRow
到 JsonObject
的自定义映射器。此映射器需要是通用映射器(它必须适用于任何查询的任何 DbRow
)。
内置映射器使用列上提供的元数据。我准备了一个简单的例子(只希望有单一类型的语句):
class DbRecordMapperProvider implements DbMapperProvider {
private static final DbMapper<JsonObject> MAPPER = new DbRecordMapper();
@SuppressWarnings("unchecked")
@Override
public <T> Optional<DbMapper<T>> mapper(Class<T> aClass) {
if (JsonObject.class.equals(aClass)) {
return Optional.of((DbMapper<T>)MAPPER);
}
return Optional.empty();
}
}
class DbRecordMapper implements DbMapper<JsonObject> {
@Override
public JsonObject read(DbRow dbRow) {
return Json.createObjectBuilder()
.add("name", dbRow.column("FIRSTPART").as(String.class))
.add("message", dbRow.column("SECONDPART").as(String.class))
.build();
}
@Override
public Map<String, ?> toNamedParameters(JsonObject dbRecord) {
return dbRecord;
}
@Override
public List<?> toIndexedParameters(JsonObject dbRecord) {
throw new IllegalStateException("Cannot convert json object to indexed parameters");
}
}
重要的方法是public JsonObject read(DbRow dbRow)
。
一旦有了这样的 DbMapperProvider
,就可以在 DbClient 中注册它:
dbClient = DbClient.builder()
.config(config.get("db"))
.mapperProvider(new DbRecordMapperProvider())
.build();