AdvanceService.java
package com.ambrosiaandrade.pets.service;
import com.ambrosiaandrade.pets.entities.AnimalEntity;
import com.ambrosiaandrade.pets.interfaces.IAnimalMapper;
import com.ambrosiaandrade.pets.models.Animal;
import com.ambrosiaandrade.pets.repositories.AnimalRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
@Slf4j
@Service
public class AdvanceService {
private final AnimalRepository repository;
private final IAnimalMapper mapper;
private final AdvanceUtil util;
@Value("${app.animal.limit:5000}")
private Long animalLimit;
public AdvanceService(AnimalRepository repository, IAnimalMapper mapper, AdvanceUtil util) {
this.repository = repository;
this.mapper = mapper;
this.util = util;
}
public List<String> generateAnimalsAndSave(int number) {
if (number <= 0) return List.of("Invalid number");
if (!verifyDataLimit()) return List.of("Maximum data limit");
List<String> list = new ArrayList<>();
try {
list.add(runAndLog("For(;;)", number, util::generateAnimalsWithFor));
list.add(runAndLog("IntStream", number, util::generateAnimalWithIntStream));
list.add(runAndLog("IntStream_parallel", number, util::generateAnimalWithIntStreamAndParallel));
} catch (DataAccessException e) {
log.error(e.getMessage());
}
return list;
}
private String runAndLog(String label, Integer number, Function<Integer, List<AnimalEntity>> generator) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<AnimalEntity> entities = generator.apply(number);
repository.saveAll(entities);
stopWatch.stop();
String result = String.format("[%s] Saved %s new entities in %s ms", label, entities.size(), stopWatch.getTotalTimeMillis());
log.info(result);
return result;
}
private boolean verifyDataLimit() {
long count = repository.count();
if (count >= animalLimit) {
log.warn("Animal limit reached: {}", count);
return false;
}
return true;
}
public List<Animal> getDataNoPagination() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
var list = repository.findAll()
.stream()
.map(mapper::toModel)
.toList();
stopWatch.stop();
log.info(String.format("[getDataNoPagination] With time %s ms", stopWatch.getTotalTimeMillis()));
return list;
}
@Cacheable("AllData")
public List<Animal> getDataNoPaginationButWithCache() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
var list = repository.findAll()
.stream()
.map(mapper::toModel)
.toList();
stopWatch.stop();
log.info(String.format("[getDataNoPaginationWithCache] With time %s ms", stopWatch.getTotalTimeMillis()));
return list;
}
public Page<Animal> getDataWithPagination(Pageable pageable) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
var list = repository.findAll(pageable)
.map(mapper::toModel);
stopWatch.stop();
log.info(String.format("[getDataWithPagination] With time %s ms", stopWatch.getTotalTimeMillis()));
return list;
}
}