在一个查询中更新多行,但我们期望的输入来自多个数据的json对象

在一个查询中更新多行,但我们期望的输入来自多个数据的json对象,json,postgresql,jpa,arraylist,Json,Postgresql,Jpa,Arraylist,上面的查询用于在一个查询中更新多行,并且工作效率也很高,但我有一个JSON: update users as u set -- postgres FTW email = u2.email, first_name = u2.first_name, last_name = u2.last_name from (values (1, 'hollis@weimann.biz', 'Hollis', 'O\'Connell'), (2, 'robert@

上面的查询用于在一个查询中更新多行,并且工作效率也很高,但我有一个JSON:

    update users as u set -- postgres FTW
    email = u2.email,
    first_name = u2.first_name,
    last_name = u2.last_name
    from (values
   (1, 'hollis@weimann.biz', 'Hollis', 'O\'Connell'),
   (2, 'robert@duncan.info', 'Robert', 'Duncan')
    ) as u2(id, email, first_name, last_name)
    where u2.id = u.id;
这样的JSON有1000个数据,我想使用JPA将这些数据插入数据库。目前,我已经通过迭代的方式插入了它,这使得我的代码速度变慢,是否有其他替代方案可以实现

任何帮助都将不胜感激

以下是我的Java代码:

   Person:{[id:1,email:"[xyz@abc.com]",first_name:"John",last_name:"Doe"],[id:2,email:"[xyz@abc.com]",first_name:"Robert",last_name:"Duncan"],[id:3,email:"[xyz@abc.com]",first_name:"Ram",last_name:"Das"],[id:4,email:"[xyz@abc.com]",first_name:"Albert",last_name:"Pinto"],[id:5,email:"[xyz@abc.com]",first_name:"Robert",last_name:"Peter"],[id:6,email:"[xyz@abc.com]",first_name:"Christian",last_name:"Lint"],[id:7,email:"[xyz@abc.com]",first_name:"Mike",last_name:"Hussey"],[id:8,email:"[xyz@abc.com]",first_name:"Ralph",last_name:"Hunter"]};
public Boolean multiEditPerson(列表个人列表){
for(个人列表:个人列表){
Person personMstr=em.find(Person.class,list.getId());
personMstr.setFirstName(list.getFirstName());
personMstr.setLastName(list.getLastName());
setEmail(Arrays.toString(list.getEmail());
em.persist(personMstr);
}
返回Boolean.TRUE;
}

诀窍是在不提交每条记录的情况下插入修补程序。如果这是一次性作业,最好在PostgreSQL端进行处理,使用Unlocked table将Json条目一次性插入数据库,然后更新主表

这里是一个exmaple文档,用于将json更改为RWO

     public Boolean multiEditPerson(List<PersonList> personList) {

        for (PersonList list : personList) {
            Person personMstr = em.find(Person.class, list.getId());
            personMstr.setFirstName(list.getFirstName());
            personMstr.setLastName(list.getLastName());
            personMstr.setEmail(Arrays.toString(list.getEmail()));
            em.persist(personMstr);
        }
        return Boolean.TRUE;
}

如果这不是一次性作业,则需要在java代码中创建批插入。不要一次处理一个人,而是处理整个人员列表

您可以基于json文档进行批量插入。您应该重新格式化文档,因为问题中显示的格式奇怪且不实用

完整工作示例:

select * from json_each('{"a":"foo", "b":"bar"}')
结果是:

create table example(id int primary key, email text, last_name text, first_name text);

with jsondata(jdata) as (
    values
    (
    '[
        {"id": 1, "email": "[xyz@abc.com]", "first_name": "John", "last_name": "Doe"},
        {"id": 2, "email": "[xyz@abc.com]", "first_name": "Robert", "last_name": "Duncan"},
        {"id": 3, "email": "[xyz@abc.com]", "first_name": "Ram", "last_name": "Das"},
        {"id": 4, "email": "[xyz@abc.com]", "first_name": "Albert", "last_name": "Pinto"},
        {"id": 5, "email": "[xyz@abc.com]", "first_name": "Robert", "last_name": "Peter"},
        {"id": 6, "email": "[xyz@abc.com]", "first_name": "Christian", "last_name": "Lint"},
        {"id": 7, "email": "[xyz@abc.com]", "first_name": "Mike", "last_name": "Hussey"},
        {"id": 8, "email": "[xyz@abc.com]", "first_name": "Ralph", "last_name": "Hunter"}
    ]'::jsonb)
)

insert into example 
select (elem->>'id')::int, elem->>'email', elem->>'last_name', elem->>'first_name'
from jsondata,
jsonb_array_elements(jdata) as elem;

如果要更新表(而不是插入到表中):


谢谢大家的回复

我使用下面的查询直接在数据库中使用JSON更新记录

with jsondata(jdata) as (
    -- values as above
)

update example set
    email = elem->>'email', 
    last_name = elem->>'last_name', 
    first_name = elem->>'first_name'
from jsondata,
jsonb_array_elements(jdata) as elem
where id = (elem->>'id')::int;

显示java代码。请参考上面的代码。-@JacekI不是java专家,我无法判断代码是否好,但在这里,我尝试了一篇小文章,它帮助我创建了一个临时表并更新了主表。正在将多个列从临时表更新到主表。请确认这是我应该在JPA中使用的还是我需要研究的其他内容。您也可以直接进行更新,无需临时缓冲区。请参阅更新的答案。
with jsondata(jdata) as (
    -- values as above
)

update example set
    email = elem->>'email', 
    last_name = elem->>'last_name', 
    first_name = elem->>'first_name'
from jsondata,
jsonb_array_elements(jdata) as elem
where id = (elem->>'id')::int;
    UPDATE person p
                SET (first_name,email,last_name)= 
                (COALESCE(ab.first_name, p.first_name)
                , COALESCE(ab.email,p.email)
                ,COALESCE(ab.last_name, p.last_name)
                     )
                FROM (
                  select * from  json_populate_recordset 
                (null::person,'[{"id":1,"first_name":"Robert","email":"robert.stark@xyz.com","last_name":"Stark"},{"id":2,"first_name":"John","email":"John.Doe@xyz.com","last_name":"Doe"}]')
                  ) ab
                WHERE p.id = ab.id;