当前位置: 首页 > 知识库问答 >
问题:

Jooq-将字段更新为NULL使其为“null”而不是NULL

许马鲁
2023-03-14

所以这是我以前在jooq 3.11中工作的查询。

我正在更新一个JSON字段,但是它使用Json绑定映射到我模型中的字符串,我将在下面发布

        dsl.update(TASK)
            .set(TASK.JSON_SOLUTION, (String) null).            
        .where(TASK.TENANT.eq(getCurrentTenant()))
        .and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()

这在升级到jooq 3.13.2后不再有效。我还不得不将我的sql方言更改为mysql,即使我正在使用mysql 5_7数据库,这可能是问题所在?

我也试过这个,它还是一样的

        dsl.update(TASK)
            .setNull(TASK.JSON_SOLUTION).            
         .where(TASK.TENANT.eq(getCurrentTenant()))
        .and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()

JsonBinding.class

public class JsonBinding implements Binding<JSON, String> {

  @Override
  public Converter<JSON, String> converter() {
    return new JsonConverter();
  }

  @Override
  public void sql(BindingSQLContext<String> bindingSQLContext) {
    if (bindingSQLContext.render().paramType() == ParamType.INLINED) {
      bindingSQLContext
          .render()
          .visit(DSL.inline(bindingSQLContext.convert(converter()).value()))
          .sql("::json");
    } else {
      bindingSQLContext.render().sql("?");
    }
  }

  @Override
  public void register(BindingRegisterContext<String> bindingRegisterContext) throws SQLException {
    bindingRegisterContext
        .statement()
        .registerOutParameter(bindingRegisterContext.index(), Types.VARCHAR);
  }

  @Override
  public void set(BindingSetStatementContext<String> bindingSetStatementContext)
      throws SQLException {
    bindingSetStatementContext
        .statement()
        .setString(
            bindingSetStatementContext.index(),
            Objects.toString(bindingSetStatementContext.convert(converter()).value(), null));
  }

  @Override
  public void set(BindingSetSQLOutputContext<String> bindingSetSQLOutputContext)
      throws SQLException {
    throw new SQLFeatureNotSupportedException();
  }

  @Override
  public void get(BindingGetResultSetContext<String> bindingGetResultSetContext)
      throws SQLException {
    bindingGetResultSetContext
        .convert(converter())
        .value(
            JSON.valueOf(
                bindingGetResultSetContext
                    .resultSet()
                    .getString(bindingGetResultSetContext.index())));
  }

  @Override
  public void get(BindingGetStatementContext<String> bindingGetStatementContext)
      throws SQLException {
    bindingGetStatementContext
        .convert(converter())
        .value(
            JSON.valueOf(
                bindingGetStatementContext
                    .statement()
                    .getString(bindingGetStatementContext.index())));
  }

  @Override
  public void get(BindingGetSQLInputContext<String> bindingGetSQLInputContext) throws SQLException {
    throw new SQLFeatureNotSupportedException();
  }
}

JsonConverter.class

public class JsonConverter implements Converter<JSON, String> {

  @Override
  public String from(JSON object) {
    return object != null ? object.toString() : null;
  }

  @Override
  public JSON to(String string) {
    return JSON.valueOf(string);
  }

  @Override
  public Class<JSON> fromType() {
    return JSON.class;
  }

  @Override
  public Class<String> toType() {
    return String.class;
  }
}

以下是jooq与.setNull()一起运行的查询

update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = 'null'::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))

在jooq 3.11升级之前,查询结果如下

update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = null::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))

因此,在设置“json\u solution”=null之前,升级之后似乎设置为“json\u solution”=“null”

不太清楚为什么会发生这种情况?

编辑:所以据我所知,这似乎只是来自JOOQ的升级,而不是sql方言。使用带有mysql和mysql_5_7的Jooq 3.11.5作为方言,查询被构建为set'json_solution'=null,如果我将JOOQ升级到3.13.2,它的set'json_solution'='null'

这种怪癖似乎只发生在JSON字段上,我尝试在同一个表中将另一个varchar字符串字段设置为null,得到了正确的设置“field\u name”=null

问题可能是我的JsonBding/JsonConverter?我不得不稍微修改它以在JOOQ中使用新的JSON对象,因为之前JOOQ将JSON映射为对象

共有1个答案

殷烨
2023-03-14

答案在org.jooq.JSON的Javadoc中:

转换(NULL为JSON)值由类型为JSON的引用表示,而不是表示为data()==NULL。这与jOOQ从结果和记录方法返回NULL的一般方法是一致的。

因此,错误在于JsonConverter对JSON.valueOf()的使用。改为写下:

  public JSON to(String string) {
    return string == null ? null : JSON.valueOf(string);
  }

或者,只需使用转换器。ofNullable(),它为您处理空到空的映射:

Converter<JSON, String> converter = Converter.ofNullable(
  JSON.class,
  String.class,
  JSON::data,
  JSON::json
);

既然jOOQ本机支持JSON类型,您就不再需要绑定了。如果您想将JSON转换为字符串,您的转换器就足够了。

 类似资料:
  • 编辑2: 似乎调用实际上是在取消数据库中的字段!但是,调用并没有像预期的那样用空字段刷新POJO。我在之后验证了lastName的为null,但是调用没有使该值为null。

  • 问题内容: 我必须编写一个例程,如果变量的类型为,则将变量的值加1,否则将变量的值分配为0,其中变量的初始值为或。 第一个实现是因为我认为没有数字会使算术表达式为假,但是由于计算为真,所以这是错误的。然后,我得知行为类似于0,并且以下表达式均被评估为true。 当然不是0。被评估为false。这使看似重言式的表达成为错误。 为什么实际上不是0,却像0? 问题答案: 您真正的问题似乎是: 为什么:

  • 问题内容: 由于空字符串是Go的零/默认值,因此我决定将所有此类字段定义为。例如 如果该值不适用于该特定字段,则我正在发送数据的应用程序期望使用null而不是空字符串。 这是正确的方法吗?或者有人可以向我指出比这更好的方法。 问题答案: 在json包文档中: 指针值编码为指向的值。nil指针编码为空JSON对象。 因此,您可以存储指向字符串的指针,如果不为nil,则将其编码为字符串;如果为nil,

  • 只有当新值不为null时,我才会更新集合设置值。我有这样一个代码: 有没有一个简单的方法可以做到这一点? 另一种方法:如果我可以从我获取数据的表单的占位符中获取值,我可以解决这个问题...但是这可能吗?

  • 我试图用一个值为0或1的布尔字段来持久化一个条令实体。 当属性设置为true时,它会在数据库中将其另存为“1”。但当其值为“false”或“0”时,它会在数据库中将其另存为NULL。 我如何解决这个问题,只保存为1或0? 我使用的属性的注释如下所示: 当我将nullable设置为false时,我不能坚持它,因为它仍然想要设置为null。 谢谢 当我将其持久化时,字段值为0 尝试1@ORM\列(名称

  • 大家好! 我正在Spring应用程序中实现Mapstruct映射器。 有两个相关实体:和。只是为了简化->用户可以有许多订单。 OrderMapper类: 好吧,我的问题是: 如果我使用以下命令传递OrderDTO: 前面描述的情况在我的应用程序中造成了巨大的问题。如果有任何帮助,我将不胜感激。