Really new in SpringBoot environment and not familiar with all the annotations and methods.
My problem is quite easy but I'm totally stuck. I have a Table Device with some columns such as Type, Constructor, Model.
I would like to count the number of devices by Model for each Constructor and Type and return a Map all those in the following format :
"numberOfDevicePerTypeConstructorModel": {
"Type1": {
"Constructor1": {
"Model1": 0,
"Model2": 0,
},
"Constructor2": {
"Model1": 0,
"Model2": 0,
}
},
"Type2": {
"Constructor1": {
"Model1": 0,
"Model2": 0,
},
"Category2": {
"Model1": 0,
"Model2": 0,
}
},
}
For Example, I could make an easy one to get a simple Map<String, Long> of the number of Device by model like this :
for (String model : deviceRepository.findDistinctModel()) {
deviceStats.numberOfDevicePerModel.put(model, deviceRepository.countByModel(model));
}
But if now I try to imbricate some "for loop" on Type and Constructor and make some intermediary Map<String, Long> it doesn't really work.
public class DeviceService() {
public class DeviceStats() {
public Map<String,Long> numberPerModel;
public Map<String,Map<String,Long>> numberPerConstructorModel;
public Map<String, Map<String,Map<String,Long>>> numberOfDevicePerTypeConstructorModel;
DeviceStats(){
numberPerModel = new HashMap<String,Long>();
numberPerConstructorModel = new HashMap<String,Map<String,Long>>();
numberOfDevicePerTypeConstructorModel = new HashMap<String,Map<String,Map<String,Long>>>();
}
}
public DeviceStats getDeviceStats() {
for(String type : deviceRepository.findDistinctType()) {
for(String constructor : deviceRepository.findDistinctConstructorByType(type)){
for (String model : deviceRepository.findDistinctModelByTypeAndConstructor(type,constructor)) {
deviceStats.numberPerModel.put(model, deviceRepository.countByModelAndConstructorAndType(model, constructor,type));
}
deviceStats.numberPerConstructorModel.put(constructor, deviceStats.numberPerModel);
}
deviceStats.numberOfDevicePerTypeConstructorModel.put(type, deviceStats.numberPerConstructorModel);
}
}
}
Hope I've been clear. Thank you for your help or advice on how to do that easily. (I'm sure it can be done within a couple of lines of code but I don't see how.)
Thanks
CodePudding user response:
If I may preach here a little bit:
I don't think is a good idea to make db calls in a for loop. Maybe it would be better if you first constructed your query in a way that suits you so, before processing, you end up having a List<DeviceStat> deviceStats
and then:
public static Map<String, Map<String, Map<String, Long>>> getDeviceStats(List<DeviceStat> deviceStats) {
return deviceStats.stream()
.collect(Collectors.groupingBy(DeviceStat::getType,
Collectors.groupingBy(DeviceStat::getConstructor,
Collectors.groupingBy(DeviceStat::getModel,
Collectors.counting()))));
}
CodePudding user response:
I don't think you need embeded class. You need something like:
public class DeviceService() {
public Map<String, Map<String, Map<String, Long>>> getDeviceStats() {
Map<String, Map<String, Map<String, Long>>> numberOfDevicePerTypeConstructorModel =
new HashMap<String, Map<String, Map<String, Long>>>();
for (String type : deviceRepository.findDistinctType()) {
Map<String, Map<String, Long>> numberPerConstructorModel = new HashMap<String, Map<String, Long>>();
numberOfDevicePerTypeConstructorModel.put(type, numberPerConstructorModel);
for (String constructor : deviceRepository.findDistinctConstructorByType(type)) {
Map<String, Long> numberPerModel = new HashMap<String, Long>();
numberPerConstructorModel.put(constructor, numberPerModel);
for (String model : deviceRepository.findDistinctModelByTypeAndConstructor(type, constructor)) {
numberPerModel.put(model, deviceRepository.countByModelAndConstructorAndType(model, constructor, type));
}
}
}
return numberOfDevicePerTypeConstructorModel;
}
}