Reputation: 85
update users as u set -- postgres FTW
email = u2.email,
first_name = u2.first_name,
last_name = u2.last_name
from (values
(1, '[email protected]', 'Hollis', 'O\'Connell'),
(2, '[email protected]', 'Robert', 'Duncan')
) as u2(id, email, first_name, last_name)
where u2.id = u.id;
Above query is used to update multiple rows in one query and it works efficiently as well but I have a JSON below:
Person:{[id:1,email:"[[email protected]]",first_name:"John",last_name:"Doe"],[id:2,email:"[[email protected]]",first_name:"Robert",last_name:"Duncan"],[id:3,email:"[[email protected]]",first_name:"Ram",last_name:"Das"],[id:4,email:"[[email protected]]",first_name:"Albert",last_name:"Pinto"],[id:5,email:"[[email protected]]",first_name:"Robert",last_name:"Peter"],[id:6,email:"[[email protected]]",first_name:"Christian",last_name:"Lint"],[id:7,email:"[[email protected]]",first_name:"Mike",last_name:"Hussey"],[id:8,email:"[[email protected]]",first_name:"Ralph",last_name:"Hunter"]};
Such JSON has 1000 data which I want to insert in the Database using JPA. Currently I have inserted it by iterating this which makes my code slow,Is there any other alternative which can be implemented.
Any help will be appreciated.
Here is my Java Code :
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;
}
Upvotes: 3
Views: 1998
Reputation: 85
Thanks for the reply to everyone !!
I have used below query to update records using JSON directly in the db.
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":"[email protected]","last_name":"Stark"},{"id":2,"first_name":"John","email":"[email protected]","last_name":"Doe"}]')
) ab
WHERE p.id = ab.id;
Upvotes: 0
Reputation: 121624
You can do a bulk insert based on the json document. You should reformat the document as the format shown in the question is strange and unpractical.
Full working example:
create table example(id int primary key, email text, last_name text, first_name text);
with jsondata(jdata) as (
values
(
'[
{"id": 1, "email": "[[email protected]]", "first_name": "John", "last_name": "Doe"},
{"id": 2, "email": "[[email protected]]", "first_name": "Robert", "last_name": "Duncan"},
{"id": 3, "email": "[[email protected]]", "first_name": "Ram", "last_name": "Das"},
{"id": 4, "email": "[[email protected]]", "first_name": "Albert", "last_name": "Pinto"},
{"id": 5, "email": "[[email protected]]", "first_name": "Robert", "last_name": "Peter"},
{"id": 6, "email": "[[email protected]]", "first_name": "Christian", "last_name": "Lint"},
{"id": 7, "email": "[[email protected]]", "first_name": "Mike", "last_name": "Hussey"},
{"id": 8, "email": "[[email protected]]", "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;
The result:
select *
from example
id | email | last_name | first_name
----+---------------+-----------+------------
1 | [[email protected]] | Doe | John
2 | [[email protected]] | Duncan | Robert
3 | [[email protected]] | Das | Ram
4 | [[email protected]] | Pinto | Albert
5 | [[email protected]] | Peter | Robert
6 | [[email protected]] | Lint | Christian
7 | [[email protected]] | Hussey | Mike
8 | [[email protected]] | Hunter | Ralph
(8 rows)
If you want to update the table (instead of insert into it):
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;
Upvotes: 3
Reputation: 525
The trick is to do a patch insertion without commit for each record. If this is a one time job, it is better to process it on the PostgreSQL side, insert the Json entries all at once to the database using unlogged table and then update you main table.
here an exmaple from documentation to change a json to rwos
select * from json_each('{"a":"foo", "b":"bar"}')
if this is not one time job, you need to create a batch insert in your java code. Do not process one person at a time but the whole list of persons.
Upvotes: 0