JOOq稀疏更新

时间:2017-07-06 01:38:00

标签: java jooq

我正在使用Jax-RS和Jooq。 我想知道如何使用稀疏数据实现REST PATCH。

我们说我有一些PoJo。我得到一个带有不完整对象的JSON PATCH(http://www.restapitutorial.com/lessons/httpmethods.html)请求,该对象只包含那些应该更改的字段。

我该怎么写这样的处理程序?

我尝试接受实际的Pojo对象。我的第一个想法是"如果一个字段为空,我不会更新它"。这是我的第一个问题。

public Resource update(@PathParam("id") UUID id, Resource resource) {
    ResourceRecord record = dslContext.newRecord(RESOURCE, resource);
    dslContext.update(RESOURCE).set(resource).where(RESOURCE.ID.eq(id)).execute();

    // or

    memberDao.update(member);

    return resourceDao.findById(id);
}

在尝试和在线搜索时,我想"故意将某些东西设置为空?"。所以它必须依赖于请求中字段的存在。

我的最后一个想法是:

public Resource update(@PathParam("id") UUID id, Map<String, Object> changes) {
    dslContext.update(RESOURCE).set(changes).where(RESOURCE.ID.eq(id)).execute();
    return resourceDao.findById(id);
}

当然不起作用(set(Map&lt; Field,...&gt;))。

但我有点卡住了,interwebz对不同的问题充满了答案,但我没有发现有人试过同样的事情。

在我的脑海里,我正在玩着反射和循环,感觉有些令人难以置信。我想知道如何尽可能简单地编写代码。

1 个答案:

答案 0 :(得分:0)

  

我尝试接受实际的Pojo对象。我的第一个想法是“如果一个字段为空,我不更新它”。这是我的第一个问题。

这不是jOOQ的工作方式。 The rationale is described in this blog post here。特别是,您的特定代码行在这里:

ResourceRecord record = dslContext.newRecord(RESOURCE, resource);

将所有ResourceRecord.changed()标记设置为true,无论它们是否为null(因此,无论它们的值是否已通过从POJO设置而被修改)。就REST而言,这与PUT相对应,远远超过PATCH

这要好得多:

public Resource update(@PathParam("id") UUID id, Map<String, Object> changes) {
    dslContext.update(RESOURCE)
              .set(translate(RESOURCE, changes))
              .where(RESOURCE.ID.eq(id))
              .execute();
    return resourceDao.findById(id);
}

您需要一个translate()函数,将Map<String, Object>翻译为Map<Field<?>, Object>,在RESOURCE中查找字段名称。

这应该是开箱即用的,当然,目前与剩余的API不一致。修复工作正在进行中:https://github.com/jOOQ/jOOQ/issues/6388

在此期间,您只需将地图传递给DSLContext.newRecord(Table, Object),即会在内部调用Record.fromMap()