Par exemple, lorsque vous souhaitez traiter le résultat extrait en joignant deux tables parent et enfant de la base de données pour chaque clé. Vous pouvez le traiter sous forme de liste, mais il est préférable de le regrouper par clé, n'est-ce pas? (Personnellement, je l'aime car il améliore la lisibilité. S'il y a un problème de performance, il ne peut pas être résolu.) Cette fois, après l'acquisition par lots avec une liste côte à côte, essayez de convertir en Map (clé: table parent, valeur: table enfant).
ER
Si vous obtenez cela par jointure interne, ce sera comme ça. ↓
select_all.sql
select *
du Département Master
maître des employés de jointure interne utilisant l'ID de service;
Image du résultat d'acquisition (Liste <résultat>) ↓
département | Employé |
---|---|
Département 1 | Employé 1 |
Département 1 | Employé 2 |
Département 2 | Employé 3 |
Département 2 | Employé 4 |
Département 2 | : |
Le but de ce temps est de convertir cela en "Mapper <département, Liste <employé >>" avec le département comme clé et l'employé comme valeur.
--DemoService: processus principal --DbMapper: en fait un mappeur OR tel que Mybatis. --DbMapperImpl: DbMapper implémenté pour les tests. --Result: Stocke le résultat de select_all.sql --Département: Table des départements --Employé: table des employés
Pour le moment, j'ai créé deux méthodes list2Map7 de ** Java7 ** version et ** Java8 (Stream API) **. Les résultats devraient être les mêmes pour les deux. Après tout, l'implémentation avec Stream API a une petite quantité de code et est facile à voir. Je ne veux vraiment pas implémenter quoi que ce soit qui n'ait rien à voir avec la logique métier. Si vous faites de votre mieux, list2Map8 peut être plus facile à voir. Cependant, il semble que le code moins lisible augmentera en plus de la classe Service.
DemoService.java
package com.example.demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class DemoService {
@Autowired
DbMapper mapper;
public void execute(String[] args) {
log.info("### START ###");
// select from DB
List<Result> list = mapper.select();
//Contenu extrait
list.forEach(System.out::println);
// List ⇒ LinkedHashMap
Map<Department, List<Employee>> map = list2Map8(list);
System.out.println();
//Résultat de la conversion de sortie
for (Map.Entry<Department, List<Employee>> entry : map.entrySet()) {
System.out.println("Key:" + entry.getKey());
entry.getValue().forEach(e -> System.out.println(" Value:" + e));
}
log.info("### END ###");
}
/**
*Conversion de liste⇒Map(java7Ver).
*
* @param list
* @return
*/
private Map<Department, List<Employee>> list2Map7(List<Result> list) {
if (list.isEmpty()) {
return Collections.emptyMap();
}
Map<Department, List<Employee>> map = new LinkedHashMap<>();
//Dernière clé
Department prevDep = null;
List<Employee> tempList = null;
for (Result result : list) {
Department dep = result.getDepartment();
//Si la clé change
if (!dep.equals(prevDep)) {
//Initialiser la liste de valeurs
tempList = new ArrayList<>();
//Ajouté à la carte avec les valeurs initialisées(Définir la référence à la carte)
map.put(dep, tempList);
//Utilisez cette touche comme clé précédente
prevDep = dep;
}
//Ajouter une valeur à tempList qui fait référence à la carte
tempList.add(result.getEmployee());
}
return map;
}
/**
*Conversion de liste⇒Map(java8Ver).
*
* @param list
* @return
*/
private Map<Department, List<Employee>> list2Map8(List<Result> list) {
// List(valeur)⇒Map(キー、valeur)Conversion en
Map<Department, List<Employee>> ret = list.stream()
.collect(Collectors.groupingBy(Result::getDepartment,
LinkedHashMap::new, Collectors.mapping(Result::getEmployee, Collectors.toList())));
return ret;
}
}
J'utilise ** LinkedHashMap ** pour conserver l'ordre d'acquisition. Il n'est pas conservé dans HashMap. (Merci pour votre commentaire et l'amélioration de la méthode de conversion.)
En fait, c'est comme utiliser Mybatis ou OR mapper.
DbMapper.java
package com.example.demo;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public interface DbMapper {
List<Result> select();
}
Renvoie des données pour le débogage.
DbMapperImpl.java
package com.example.demo;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public class DbMapperImpl implements DbMapper {
@Override
public List<Result> select() {
List<Result> list = new ArrayList<>();
list.add(getResult(1, 101));
list.add(getResult(1, 102));
list.add(getResult(2, 203));
list.add(getResult(3, 304));
list.add(getResult(3, 305));
list.add(getResult(3, 306));
return list;
}
private Result getResult(int did, int eid) {
Department department = new Department();
department.setDepartmentId(did);
department.setDepartmentName("système" + did + "Division");
Employee employee = new Employee();
employee.setEmployeeId(eid);
employee.setName("Yamada" + eid + "Ro");
employee.setDepartmentId(department.getDepartmentId());
Result result = new Result(department, employee);
return result;
}
}
Objet dans lequel le résultat SELECT de la base de données est stocké en premier.
Result.java
package com.example.demo;
import lombok.Data;
@Data
public class Result {
private Department department;
private Employee employee;
public Result() {
}
public Result(Department department, Employee employee) {
this.department = department;
this.employee = employee;
}
}
Chef de département. @Data de Lombok remplace le hashcode et est égal à. Il en va de même pour le maître des employés. Selon la situation, si cela représente réellement un enregistrement dans la table, alors PK est le seul champ à remplacer. Dans ce cas, créez le vôtre sans utiliser @Data. Le remplacement est requis car LinkedHashMap (HashMap) est utilisé.
Department.java
package com.example.demo;
import lombok.Data;
@Data
public class Department {
private Integer departmentId;
private String departmentName;
}
Maître des employés.
Employee.java
package com.example.demo;
import lombok.Data;
@Data
public class Employee {
private Integer employeeId;
private String name;
private Integer departmentId;
}
Il est correctement converti en une carte pour chaque clé (département).
Résultat d'exécution
Result(department=Department(departmentId=1, departmentName=Section système 1), employee=Employee(employeeId=101, name=Yamada 101ro, departmentId=1))
Result(department=Department(departmentId=1, departmentName=Section système 1), employee=Employee(employeeId=102, name=102ro Yamada, departmentId=1))
Result(department=Department(departmentId=2, departmentName=Section système 2), employee=Employee(employeeId=203, name=Yamada 203ro, departmentId=2))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=304, name=Yamada 304ro, departmentId=3))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=305, name=Yamada 305ro, departmentId=3))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=306, name=Yamada 306ro, departmentId=3))
Key:Department(departmentId=1, departmentName=Section système 1)
Value:Employee(employeeId=101, name=Yamada 101ro, departmentId=1)
Value:Employee(employeeId=102, name=102ro Yamada, departmentId=1)
Key:Department(departmentId=2, departmentName=Section système 2)
Value:Employee(employeeId=203, name=Yamada 203ro, departmentId=2)
Key:Department(departmentId=3, departmentName=Section système 3)
Value:Employee(employeeId=304, name=Yamada 304ro, departmentId=3)
Value:Employee(employeeId=305, name=Yamada 305ro, departmentId=3)
Value:Employee(employeeId=306, name=Yamada 306ro, departmentId=3)
Lombok est pratique, n'est-ce pas?
Recommended Posts