В моем приложении Spring Boot каждый час я получаю новые данные о родителях и дочерних элементах из ответа, с которым мне нужно обновить базу данных. Ответ может содержать новых родителей, новых детей, существующих родителей с обновлениями, и если родитель и / или ребенок не присутствует в ответе, их необходимо удалить из базы данных.
Все это должно происходить в одной транзакции, чтобы избежать условий гонки.
У меня есть родительская таблица, как показано ниже:
Parent table
id | name | age | email | child_id
----------------------------------
И дочерняя таблица с внешним ключом для Parent:
Child table
id | parent_id | name
---------------------
и таблица сопоставления
id | parent_id | child_id
-------------------------
1.) Первый подход состоит в том, чтобы вставить при дублировании «имя» обновить все новые родительские данные, затем вставить новые дочерние данные, затем удалить все дочерние данные, которые не содержатся в ответе, а затем окончательно удалить все родительские данные, которые не содержится в ответе
Что-то вроде:
//For each new parent run native query
INSERT INTO PARENT (name) VALUES (name, age, email)
ON DUPLICATE KEY
UPDATE name=name, age=age, email=email;
//For each new child insert with native query
INSERT INTO CHILD (name) VALUES (name)
ON DUPLICATE KEY
UPDATE name=name
//Remove old Child data
DELETE FROM CHILD WHERE name not in (new_child_name_list);
//Remove old Parent Data
DELETE FROM Parent WHERE name not in (new_parent_name_list);
Чтобы ускорить процесс и выполнить пакет, я бы поддерживал свою собственную транзакцию в EntityManager и выполнял вышеуказанную последовательность действий. Я беспокоюсь о производительности и возможности объединения некоторых из этих операций. Я также не знаю, как я мог установить отображение, просто используя собственные запросы
2.) Я получаю все данные из базы данных и сам выполняю всю логику в Java.
public void refresh(List<Parent> newParents, List<Child> newChildren) {
//EntityManager transaction logic here
List<ParentEntity> oldParents = parentRepo.findAll();
List<ChildEntity> oldChildren = childRepo.findAll();
for(ParentEntity oldParent : oldParents) {
if (/* old matches a new parent */) {
//update matching old parent to new parent
//add associated children to parent before save
} else {
// no match, delete old parent
}
}
}
Лучше ли иметь несколько SQL-операций с нативными запросами или выполнять большую часть работы в Java?
РЕДАКТИРОВАТЬ: ясность отношений «многие ко многим»