Доброго времени суток!
Имеется сущность Translation (Entity).
@Entity @Data
@Table(name = "translations")
public class Translation {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long translationId;
@Column
private String locale;
@Lob
@Column(name = "messagekey", length = 3000)
private String key;
@Lob
@Column(name = "messagecontent", length = 100000)
private String content;
}
Сама таблица translations:
+----------------+-------------------------+------------+--------+
| translation_id | messagecontent | messagekey | locale |
+----------------+-------------------------+------------+--------+
| 1 | текст на русском | key1 | ru |
| 2 | text in english | key1 | en |
| 3 | text auf Deutsch | key1 | de |
| 4 | другой текст на русском | key2 | ru |
| 5 | other text in english | key2 | en |
| 6 | andere text auf Deutsch | key2 | de |
+----------------+-------------------------+------------+--------+
Задача - нужно объединить данные таким образом, чтобы в конечном счете получить примерно такую структуру:
+------------+-------------------------+-----------------------+-------------------------+
| messagekey | ru | en | de |
+------------+-------------------------+-----------------------+-------------------------+
| key1 | текст на русском | text in english | text auf Deutsch |
| key2 | другой текст на русском | other text in english | andere text auf Deutsch |
+------------+-------------------------+-----------------------+-------------------------+
Говоря проще, нужно из вертикальной структуры таблицы перевести в горизонтальную.
Соответственно вопрос:
На каком уровне это лучше сделать?
- На уровне MySQL (есть ли готовое решение в синтаксисе JPQL или нужно использовать nativeQuery). Если да, то что именно? GROUP_CONCAT, CONCAT, GROUP BY etc.
- На уровне Java кода. Тогда вопрос - как итерировать по 3-м спискам одновременно? Притом, что длина списков может отличаться.
Stream.concat(listA.stream(), listB.stream())
позволяет итерировать по 2-м спискам.
Мое текущее решение, хоть и не самое хорошее...
List<Translation> translations_DE = translationService.findAllByLocale("de");
List<Translation> translations_RU = translationService.findAllByLocale("ru");
List<Translation> translations_EN = translationService.findAllByLocale("en");
List<TranslationDTO> translationDTOS = new ArrayList<>();
int len = translations_DE.size();
len = Math.max(len, translations_RU.size());
len = Math.max(len, translations_EN.size());
for (int i = 0; i < len; i++) {
String translationKey = translations_DE.get(i).getKey();
Long translationId_DE = translations_DE.get(i).getTranslationId();
Long translationId_RU = translations_RU.get(i).getTranslationId();
Long translationId_EN = translations_EN.get(i).getTranslationId();
String translationContent_DE = translations_DE.get(i).getContent();
String translationContent_RU = translations_RU.get(i).getContent();
String translationContent_EN = translations_EN.get(i).getContent();
TranslationDTO translationDTO = new TranslationDTO();
translationDTO.setKey(translationKey);
translationDTO.setId_DE(translationId_DE);
translationDTO.setId_RU(translationId_RU);
translationDTO.setId_EN(translationId_EN);
translationDTO.setContent_DE(translationContent_DE);
translationDTO.setContent_RU(translationContent_RU);
translationDTO.setContent_EN(translationContent_EN);
translationDTOS.add(translationDTO);
}
Буду рад любой подсказке! Заранее спасибо)
Я так понимаю, что это Pivot Table. Но насколько мне известно, в MySQL его и нет.
SELECT "messagekey",
SUM("locale" = 'de') AS de,
SUM("locale" = 'ru') AS ru,
SUM("locale" = 'en') AS en
FROM "translations"
GROUP BY "messagekey";
Дает похожий результат... Только вместо текста из столбца messagecontent выводит цифры (я так понимаю сумму)
+------------+----+----+----+
| messagekey | de | ru | en |
+------------+----+----+----+
| key1 | 1 | 1 | 1 |
| key2 | 1 | 1 | 1 |
+------------+----+----+----+