#java #java-8 #java-stream
#java #java-8 #java-stream
Вопрос:
У меня ситуация, когда мне приходится объединять две таблицы, которые сопоставляются с OneToMany. Я хочу знать, есть ли API в потоке java 8, который может создавать единый объект, столбцы которого из левой таблицы являются обычными членами, а правая таблица — списком значений.
Пример данных:
Таблица 1
id name
1 abc
Таблица 2
id table1_id note
1 1 qwerty
2 1 asdfgh
3 1 zxcvbn
Объединение этих двух таблиц. Я получаю что-то вроде этого
select name, note from table1 join table2 on table2.table1_id=table1.id;
abc qwerty
abc asdfgh
abc zxcvbn
Текущий выходной объект java — это список следующего класса
class NotesComments{
String name;
String notes;
}
Ожидаемый результат — один класс Java с несколькими примечаниями :
class NotesComments{
String name;
List<String> notes;
}
Комментарии:
1. Я знаю, что могу использовать groupingBy, если его один столбец уникален. Но из первой таблицы есть более одного столбца, значения которого уникальны
2. Начните с написания базовой
for
версии цикла вашего кода, а затем создайте его с использованием streams, если это действительно практично. Определите структуры данных для представления данных, которыми вы поделились в вопросе. Кроме того: что, если в таблице 1 есть другая запись как:1 , xyz
и1, pqr
также?3. Что вы пробовали до сих пор?
4. @Naman в table1 id является первичным ключом, поэтому этого не произойдет
Ответ №1:
Для этого вы можете использовать API коллекторов на основе java — 8.
Вы можете увидеть этот пример
class Table2 {
int id;
int table1_id;
String note;
public Table2(int id, int table1_id, String note) {
this.id = id;
this.table1_id = table1_id;
this.note = note;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getTable1_id() {
return table1_id;
}
public void setTable1_id(int table1_id) {
this.table1_id = table1_id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
class Table1 {
private int id;
private String name;
Table1(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// Table3Final — Как вы упомянули в своем вопросе.
Stream<Table1> table1List = Stream.of(new Table1(1, "abc"));
Stream<Table2> table2List = Stream.of(new Table2(1, 1, "qwerty"),
new Table2(2, 1, "asdfgh"),
new Table2(3, 1, "zxcvbn"));
Stream<Table3Final> table3GeneratedStream = table1List
.flatMap(en -> table2List
.filter(table2Entry -> en.getId() == table2Entry.getTable1_id())
.collect(Collectors.groupingBy(Table2::getTable1_id, Collectors.mapping(Table2::getNote, Collectors.toList())))
.entrySet()
.stream()
.map(mapEntry -> new Table3Final(en.getName(), mapEntry.getValue())));
/*System.out.println(table3GeneratedStream.count());*/
table3GeneratedStream.forEach(entry -> {
System.out.println("--------------Name---------------------------");
System.out.println(entry.getName());
System.out.println("----------------Notes-------------------------");
entry.notes.forEach(System.out::println);
});
Комментарии:
1. Я думаю, вы неправильно поняли мой вопрос. 3-й таблицы нет, и я не хочу запускать два запроса, когда я могу получить результаты в одном запросе
2. Если вы видите код с потоковой операцией, он объединяет несколько потоков и выдает вам собранные (сгруппированные) выходные данные. Если вы не хотите собирать результат в потоке table3, вы можете заменить операции сопоставления на foreach и распечатать результат.