Java JOOq稀疏更新

Java JOOq稀疏更新,java,jooq,Java,Jooq,我正在使用Jax-RS和Jooq。 我想知道如何使用稀疏数据实现REST补丁 假设我有一些PoJo。我得到一个JSON补丁()请求,其中包含一个不完整的对象,该对象只包含应该更改的字段 我将如何编写这样一个处理程序 我试着接受实际的Pojo对象。我的第一个想法是“如果一个字段为空,我就不更新它”。这是我的第一个问题 public Resource update(@PathParam("id") UUID id, Resource resource) { ResourceRecord re

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

假设我有一些PoJo。我得到一个JSON补丁()请求,其中包含一个不完整的对象,该对象只包含应该更改的字段

我将如何编写这样一个处理程序

我试着接受实际的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);
}
在尝试和在线搜索时,我想“故意将某物设置为null怎么样?”。因此,它必须取决于请求中字段的存在

我最后的想法是:

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);
}
公共资源更新(@PathParam(“id”)UUID id,映射更改){
dslContext.update(RESOURCE).set(changes).where(RESOURCE.ID.eq(ID)).execute();
返回resourceDao.findById(id);
}
当然,这不起作用(设置(Map

但是我有点困了,interwebz上有很多不同问题的答案,但我没有发现有人尝试过同样的事情

在我的脑海里,我在玩反射和循环,感觉有点可怕。我想知道如何尽可能简单地编写代码

我试着接受实际的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);
}
jOOQ不是这样工作的。具体而言,您的特定代码行如下:

ResourceRecord record = dslContext.newRecord(RESOURCE, resource);
将所有标志设置为
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);
}
公共资源更新(@PathParam(“id”)UUID id,映射更改){
dslContext.update(资源)
.set(翻译(资源、更改))
.where(RESOURCE.ID.eq(ID))
.execute();
返回resourceDao.findById(id);
}
您需要一个
translate()
函数来将
Map
转换为
Map
我试着接受实际的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);
}
jOOQ不是这样工作的。具体而言,您的特定代码行如下:

ResourceRecord record = dslContext.newRecord(RESOURCE, resource);
将所有标志设置为
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);
}
公共资源更新(@PathParam(“id”)UUID id,映射更改){
dslContext.update(资源)
.set(翻译(资源、更改))
.where(RESOURCE.ID.eq(ID))
.execute();
返回resourceDao.findById(id);
}

您需要一个
translate()
函数来将
Map
转换为
Map。请确保不要将
Map
(或任何数据结构)从客户端传递到数据库。这是一个安全漏洞。攻击者可以猜测私有数据库字段并对其进行更改(例如admin=true)。只需确保不会将未选中的
映射
(或任何数据结构)从客户端传递到数据库即可。这是一个安全漏洞。攻击者可以猜测私有数据库字段并对其进行更改(例如admin=true)。