Фильтрация и объединение таблиц базы данных в Spring Batch ItemReader

#mysql #spring #jpa #spring-batch

Вопрос:

Я знаком с концепцией пакетных заданий весной, но я использовал ее только в простых сценариях, где repository используется один, который управляет одним простым объектом. Кроме того, в этих сценариях я использовал файл в качестве источника входных данных и таблицу базы данных в качестве места назначения вывода. Теперь мне нужно сделать прямо противоположное со сложными объектами.

Каков наш план

Пакетное задание получает два параметра LocalDateTime , которые охватывают интервал времени. Давайте позвоним им timeParam1 и timeParam2 .

У меня есть две таблицы TableA и TableB.

  • TableB имеет столбец, который является внешним ключом TableA вызываемого ID
  • TableB есть столбец , который LocalDateTime называется, давайте назовем его TIME

Теперь, на первом этапе моей пакетной работы, мне нужно сделать следующее:

  1. SELECT * FROM TableA a JOIN TableB b ON a.ID = b.ID для того, чтобы объединить все записи TableB , принадлежащие определенной записи TableA .
  2. Отфильтруйте те строки, которых TIME нет в заданном интервале времени.
  3. Верните все записи TableA , которые содержатся в оставшемся наборе результатов. Каждая запись должна быть возвращена только один раз, поэтому, если у recordA есть несколько записей, соответствующих критериям, recordA не следует возвращать несколько раз. На стороне java конечный результат должен быть возвращен в виде списка используемых объектов сущностей List<A>

Затем процессор превратит каждый A объект в списке в a List<String> , а писатель будет отвечать за запись этих строк в файл, каждый в одной строке.

В одном SQL — запросе это, вероятно, будет

 SELECT * FROM TableA WHERE nr IN 
    (SELECT DISTINCT a.nr FROM TableA a JOIN TableB b ON a.ID = b.ID 
     WHERE timeParam1<= b.TIME AND b.TIME <= timeParam2
 

nr это просто атрибут таблицы.

Я пытался сделать это с Spring Batch API помощью, но не смог этого сделать. Кто-нибудь может дать несколько советов о том, как мне следует подойти к этому?

Комментарии:

1. У вас уже есть запрос в 1. Зачем писать sql-запрос? Что-то вроде SELECT DISTINCT a FROM TABLEA a WHERE a.b.TIME BETWEEN :timeParam1 AND :timeParam2 . Почему запрос JPA должен быть более сложным, чем это? Если это не работает (вероятно, не работает, потому что B-это коллекция), пожалуйста, добавьте свои сущности для получения дополнительной помощи).

2. Проблема на самом деле не в запросе, а в том, как я могу его выполнить. Я знаю, что при пакетной обработке с Spring вы используете repository s для запроса источника данных, но они управляют только одним конкретным объектом. В моей постановке задачи мне нужно запросить две таблицы, чтобы задействовать больше сущностей. Что мне нужно в этом случае?

3. Ваше понимание неверно. Кроме того, вам не нужен репозиторий, вы можете сделать это с помощью обычного менеджера сущностей. Но, как указано, пожалуйста, покажите свои сущности (когда вы упоминаете JPA, они у вас должны быть, и, пожалуйста, упомяните сущности, а не таблицы!).