我在从这个问题中已经提到的PL/pgSQL 用户定义函数(结果返回JSON 数据类型)访问生成例程的字段时遇到问题。
这是我get_all_orders()
在 JSON 类型的 PL/pgSQL 中创建的函数的结果:
{
"orders": [
{
"order_id": 1,
"total_price": 29.99,
"order_date": "2019-08-22T10:06:33",
"user": {
"user_id": 1,
"username": "test"
},
"order_items": [
{
"order_item_id": 1,
"amount": 1,
"book": {
"book_id": 1,
"title": "Harry Potter and the Philosopher's Stone",
"price": 29.99,
"amount": 400,
"is_deleted": false,
"authors": [
{
"author_id": 4,
"first_name": "JK",
"last_name": "Rowling"
}
],
"categories": [
{
"category_id": 2,
"name": "Lyric",
"is_deleted": false
}
]
},
"order_id": 1,
"total_order_item_price": 29.99
}
]
},
{
"order_id": 2,
"total_price": 29.99,
"order_date": "2019-08-22T10:10:13",
"user": {
"user_id": 1,
"username": "test"
},
"order_items": [
{
"order_item_id": 2,
"amount": 1,
"book": {
"book_id": 1,
"title": "Harry Potter and the Philosopher's Stone",
"price": 29.99,
"amount": 400,
"is_deleted": false,
"authors": [
{
"author_id": 4,
"first_name": "JK",
"last_name": "Rowling"
}
],
"categories": [
{
"category_id": 2,
"name": "Lyric",
"is_deleted": false
}
]
},
"order_id": 2,
"total_order_item_price": 29.99
}
]
}
]
}
我正在尝试按照自定义数据类型绑定手册将例程作为字段访问,到目前为止我设法创建自定义转换器以便将org.jooq.JSON转换为io.vertx.core.json.JsonObject:
public class JSONJsonObjectConverter implements Converter<JSON, JsonObject>{
private static final long serialVersionUID = -4773701755042752633L;
@Override
public JsonObject from(JSON jooqJson) {
String strVal = (jooqJson == null ? null : jooqJson.toString());
return strVal == null ? null : JsonObject.mapFrom(strVal);
}
@Override
public JSON to(JsonObject vertxJson) {
String strVal = (vertxJson == null ? null : vertxJson.toString());
return strVal == null ? null : JSON.valueOf(strVal);
}
@Override
public Class<JSON> fromType() {
return JSON.class;
}
@Override
public Class<JsonObject> toType() {
return JsonObject.class;
}
}
...这是指向QueryResult 源代码的链接,我正在使用此方法来调用它(自定义创建的转换器):
public static JsonObject convertGetAllOrdersQRToJsonObject(QueryResult qr) {
//JsonArray ordersJA = qr.get("orders", JsonArray.class);
DataType<JsonObject> jsonObjectType = SQLDataType.JSON.asConvertedDataType(new JSONJsonObjectConverter());
//DataType<JsonArray> jsonArrayType = SQLDataType.JSONArray.asConvertedDataType(new JsonArrayConverter());
DataType<JsonObject> jsonObjectTypeDefault = SQLDataType.JSON.asConvertedDataType((Binding<? super JSON, JsonObject>) new JsonObjectConverter());
Field<JsonObject> ordersFieldDefault = DSL.field("get_all_orders", jsonObjectTypeDefault);
Field<JsonObject> ordersField = DSL.field("get_all_orders", jsonObjectType);
JsonObject orders = qr.get("orders", JsonObject.class);
// return new JsonObject().put("orders", orders);
return new JsonObject().put("orders", ordersField); // try ordersFieldDefault(.toString()) as value parameter
}
我在以下方法中调用上述方法:
Future<QueryResult> ordersFuture = queryExecutor.transaction(qe -> qe
.query(dsl -> dsl
.select(Routines.getAllOrders())
));
LOGGER.info("Passed ordersFuture...");
ordersFuture.onComplete(handler -> {
if (handler.succeeded()) {
QueryResult qRes = handler.result();
JsonObject ordersJsonObject = OrderUtilHelper.convertGetAllOrdersQRToJsonObject(qRes);
LOGGER.info("ordersJsonObject.encodePrettily(): " + ordersJsonObject.encodePrettily());
resultHandler.handle(Future.succeededFuture(ordersJsonObject));
} else {
LOGGER.error("Error, something failed in retrivening ALL orders! handler.cause() = " + handler.cause());
queryExecutor.rollback();
resultHandler.handle(Future.failedFuture(handler.cause()));
}
});
...这是在Routines.java 类中生成的方法,该方法在上面最后提到的代码中用于将值返回到dsl -> dsl.select(Routines.getAllOrders())
语句部分的表达式中:
/**
* Convenience access to all stored procedures and functions in public
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class Routines {
/**
* Get <code>public.get_all_orders</code> as a field.
*/
public static Field<JSON> getAllOrders() {
GetAllOrders f = new GetAllOrders();
return f.asField();
}
}
...和(最后)这是我的*.jooq.routines.GetAllOrders.java
课:
/**
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class GetAllOrders extends AbstractRoutine<JSON> {
private static final long serialVersionUID = 917599810;
/**
* The parameter <code>public.get_all_orders.RETURN_VALUE</code>.
*/
public static final Parameter<JSON> RETURN_VALUE = Internal.createParameter("RETURN_VALUE", org.jooq.impl.SQLDataType.JSON, false, false);
/**
* Create a new routine call instance
*/
public GetAllOrders() {
super("get_all_orders", Public.PUBLIC, org.jooq.impl.SQLDataType.JSON);
setReturnParameter(RETURN_VALUE);
}
}
顺便说一句,Vertx 库还使用JsonArray类,该类用于处理数组,但我看不到将已经生成的 org.jooq.JSON 映射到类型org.jooq.impl.JSONArray
然后再映射到io.vertx.core.json.JsonArray
类型的方法。
我是否遗漏了一些东西(我知道我正在处理生成的 Routine,但 jOOQ 手册中给出的示例仅包含 Table 字段)......或者我应该创建自定义数据类型绑定类?
非常感谢任何建议/帮助。
更新1:
我已按照评论中链接的问答中给出的说明进行操作,这就是我添加的内容,并且已经<forcedType>
在我的 s 中pom.xml
:
<!-- Convert varchar column with name 'someJsonObject' to a io.vertx.core.json.JsonObject -->
<forcedType>
<userType>io.vertx.core.json.JsonObject</userType>
<converter>io.github.jklingsporn.vertx.jooq.shared.JsonObjectConverter</converter>
<includeExpression>someJsonObject</includeExpression>
<includeTypes>.*</includeTypes>
<nullability>ALL</nullability>
<objectType>ALL</objectType>
</forcedType>
<!-- Convert varchar column with name 'someJsonArray' to a io.vertx.core.json.JsonArray -->
<forcedType>
<userType>io.vertx.core.json.JsonArray</userType>
<converter>
io.github.jklingsporn.vertx.jooq.shared.JsonArrayConverter</converter>
<includeExpression>someJsonArray</includeExpression>
<includeTypes>.*</includeTypes>
<nullability>ALL</nullability>
<objectType>ALL</objectType>
</forcedType>
<forcedType>
<userType>io.vertx.core.json.JsonObject</userType>>
<!-- also tried to use "org.jooq.Converter.ofNullable(Integer.class, String.class, Object::toString, Integer::valueOf)"
and it did NOT work so I gave this custom created Conveter a try and it ALSO did NOT work! -->
<converter>
com.ns.vertx.pg.converters.JSONJsonObjectConverter.ofNullable(JSON.class, JsonObject.class, JsonObject::toString, JSON::valueOf)
</converter>
<includeExpression>(?i:get_all_orders|return_value)</includeExpressio>
</forcedType>
...当我执行 Maven> Update Project + 检查强制更新快照/发布时,我总共收到 32 条错误消息:
JsonObject 无法解析
...和
JsonObject 无法解析为类型
...这是我生成的*.jooq.routines.GetAllOrders.java
类:
// This class is generated by jOOQ.
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class GetAllOrders extends AbstractRoutine<JsonObject> {
private static final long serialVersionUID = -431575258;
// The parameter <code>public.get_all_orders.RETURN_VALUE</code>.
public static final Parameter<JsonObject> RETURN_VALUE = Internal.createParameter("RETURN_VALUE", org.jooq.impl.SQLDataType.JSON, false, false, org.jooq.Converter.ofNullable(JSON.class, JsonObject.class, JsonObject::toString, JSON::valueOf));
//Create a new routine call instance
public GetAllOrders() {
super("get_all_orders", Public.PUBLIC, org.jooq.impl.SQLDataType.JSON, org.jooq.Converter.ofNullable(JSON.class, JsonObject.class, JsonObject::toString, JSON::valueOf));
setReturnParameter(RETURN_VALUE);
}
}
我已经为这个生成器ClassicReactiveVertxGenerator提供了这些以编程方式创建的转换器(有关它的更多信息可在此处获得),用于io.vertx.core.json.JsonObject
第一次提到的<forcedType>
。任何建议如何解决这个问题?
UPDATE2:
我也尝试过org.jooq.Converter
像这样使用这个转换器(必须对 JSON 类使用合格的引用,否则它不会在 Generated Routine clases 中执行导入):
<forcedType>
<userType>java.lang.String</userType>
<converter>
org.jooq.Converter.ofNullable(org.jooq.JSON.class, String.class, Object::toString,org.jooq.JSON.class::valueOf)
</converter>
<includeExpression>(?i:get_all_orders|return_value) </includeExpression>
</forcedType>
...我在生成的 GetAllOrders.java 类中得到了这个:
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class GetAllOrders extends AbstractRoutine<String> {
private static final long serialVersionUID = 1922028137;
// The parameter <code>public.get_all_orders.RETURN_VALUE</code>.
public static final Parameter<String> RETURN_VALUE = Internal.createParameter("RETURN_VALUE", org.jooq.impl.SQLDataType.JSON, false, false, org.jooq.Converter.ofNullable(org.jooq.JSON.class, String.class, Object::toString, org.jooq.JSON.class::valueOf));
// in above value I get ERROR "The method ofNullable(Class<T>, Class<U>, Function<? super T,? extends U>, Function<? super U,? extends T>) in the type Converter is not applicable for the arguments (Class<JSON>, Class<String>, Object::toString, org.jooq.JSON.class::valueOf)"
// ... for org.jooq.Converter.ofNullable(..) method + 23 same/similar ERRORS
// Create a new routine call instance
public GetAllOrders() {
super("get_all_orders", Public.PUBLIC, org.jooq.impl.SQLDataType.JSON, org.jooq.Converter.ofNullable(org.jooq.JSON.class, String.class, Object::toString, org.jooq.JSON.class::valueOf));
setReturnParameter(RETURN_VALUE);
}
}
由于这不起作用,我试图通过创建JooqJsonConverter.java
自定义转换器类来解决这个问题,如下所示:
public class JooqJsonConverter implements Converter<String, JSON>{
private static final long serialVersionUID = -4773701755042752633L;
@Override
public JSON from(String jooqJson) { return jooqJson == null ? null : JSON.valueOf(jooqJson); }
@Override
public String to(JSON jooqJson) { return jooqJson == null ? null : jooqJson.toString(); }
@Override
public Class<String> fromType() { return String.class; }
@Override
public Class<JSON> toType() { return JSON.class; }
}
...并更改标签下的转换器:
<converter>
com.ns.vertx.pg.converters.JooqJsonConverter.ofNullable(org.jooq.JSON.class, String.class, Object::toString,org.jooq.JSON.class::valueOf)
</converter>
...我得到相同的代码 GetAllOrders.java 类,差异很小
public static final Parameter<String> RETURN_VALUE = Internal.createParameter("RETURN_VALUE", org.jooq.impl.SQLDataType.JSON, false, false, com.ns.vertx.pg.converters.JooqJsonConverter.ofNullable(org.jooq.JSON.class, String.class, Object::toString, org.jooq.JSON.class::valueOf));
public GetAllOrders() {
super("get_all_orders", Public.PUBLIC, org.jooq.impl.SQLDataType.JSON, com.ns.vertx.pg.converters.JooqJsonConverter.ofNullable(org.jooq.JSON.class, String.class, Object::toString, org.jooq.JSON.class::valueOf));
setReturnParameter(RETURN_VALUE);
}
...并且只有这 8 个错误(4 个生成的 Routine 类中的每一个都有 2 个):
对于 JooqJsonConverter 类型,未定义方法 ofNullable(Class, Class, Object::toString, org.jooq.JSON.class::valueOf)
知道缺少什么/我做错了吗?先感谢您。