добавлена работа со списками продуктов, попытка оптимизировать запрос по поиску коктейлей

This commit is contained in:
Kayashov.SM
2025-05-03 01:36:17 +04:00
parent badd71545e
commit 9809a19762
13 changed files with 269 additions and 43 deletions

View File

@@ -3,11 +3,15 @@ package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.model.entity.Category;
import ru.kayashov.bar.model.entity.Glass;
@@ -52,6 +56,26 @@ public class BarController {
return sessionService.getReceiptList(id);
}
@PostMapping("/change/{id}")
public void changeActiveBar(@PathVariable Long id) {
sessionService.changeActiveBar(id);
}
@DeleteMapping("/{id}")
public void deleteBar(@PathVariable Long id) {
sessionService.deleteBar(id);
}
@PostMapping("/{name}")
public BarResponseDto createBar(@PathVariable String name) {
return sessionService.createBar(name);
}
@GetMapping("/all")
public List<BarResponseDto> getAll() {
return sessionService.findAllBar();
}
@GetMapping("/getMe")
public VisitorResponseDto getMe() {
Visitor visitor = visitorService.getCurrentVisitor();

View File

@@ -2,13 +2,20 @@ package ru.kayashov.bar.controller.dto.bar;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.BarEntity;
@Getter
@Setter
public class BarResponseDto {
private Long id;
private String name;
private Boolean open;
private Boolean enter;
private String myRole;
private Boolean active;
public static BarResponseDto mapToDto(BarEntity barEntity) {
BarResponseDto barResponseDto = new BarResponseDto();
barResponseDto.setId(barEntity.getId());
barResponseDto.setName(barEntity.getName());
barResponseDto.setActive(barEntity.getActive());
return barResponseDto;
}
}

View File

@@ -31,6 +31,7 @@ public class IngredientEntity {
private String enName;
private Boolean alcohol;
private Integer abv;
private Boolean isHave;
@Column(columnDefinition = "text")
private String description;

View File

@@ -15,14 +15,12 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.mapper.CocktailMapper;
import ru.kayashov.bar.model.Ingredient;
import ru.kayashov.bar.model.entity.Alcoholic;
import ru.kayashov.bar.model.entity.Category;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.Glass;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.ReceiptRepository;
@@ -37,7 +35,6 @@ import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import javax.print.attribute.standard.MediaSize;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -82,7 +79,8 @@ public class CocktailService {
criteriaQuery.distinct(true);
if (!dto.getAll()) {
List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
// List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
List<Long> cocktailIds = findCocktailByCountNotHaveIngredient();
Predicate pr = root.get("id").in(cocktailIds);
predicates.add(pr);
}
@@ -225,35 +223,18 @@ public class CocktailService {
group by r.cocktail_id) as cifc
where false_count = 0
*/
private List<Long> findCocktailByCountNotHaveIngredient(Integer notHaveCount, List<Long> currentIngredient) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
List<Predicate> predicates = new ArrayList<>();
CriteriaQuery<Long> mainQuery = cb.createQuery(Long.class);
//todo: так и не придумал я нормальный запрос
private List<Long> findCocktailByCountNotHaveIngredient() {
String sql = "SELECT cifc.cocktail_id" +
" FROM (SELECT r.cocktail_id," +
" COUNT(CASE WHEN i.is_have = false THEN 1 END) AS false_count" +
" FROM receipt r" +
" LEFT JOIN public.ingredient i ON i.id = r.ingredient_id" +
" GROUP BY r.cocktail_id) AS cifc" +
" WHERE false_count = 0";
// Создаем корневые сущности
Subquery<Long> sq = mainQuery.subquery(Long.class);
Root<ReceiptEntity> rsq = sq.from(ReceiptEntity.class);
Join<ReceiptEntity, IngredientEntity> ingredientJoin = rsq.join("ingredient", JoinType.LEFT);
// Создаем подзапрос
sq.select(cb.count(cb.selectCase(cb.isFalse(ingredientJoin.get("isHave")))))
.groupBy(rsq.get("cocktail"))
.having(cb.equal(sq.getSelection(), notHaveCount));
// Создаем внешний запрос
mainQuery.select(rsq.get("cocktail"));
Predicate predicate = cb.exists(sq);
predicates.add(predicate);
// mainQuery.where(cb.exists(sq));
if(!currentIngredient.isEmpty()) {
predicates.add(rsq.get("ingredient").in(currentIngredient));
}
mainQuery.where(predicates.toArray(new Predicate[0]));
// Выполняем запрос
return entityManager.createQuery(mainQuery)
.getResultList();
javax.persistence.Query query = entityManager.createNativeQuery(sql);
return query.getResultList();
}
public CocktailForListResponseDto findById(Long id) {

View File

@@ -25,6 +25,7 @@ public class IngredientService {
private final IngredientRepository repository;
private final IngredientMapper mapper;
private final BarEntityRepository barEntityRepository;
private final IngredientRepository ingredientRepository;
private TypeEntity findTypeByName(String name) {
return typeRepository.findByName(name)
@@ -57,6 +58,8 @@ public class IngredientService {
} else {
bar.getIngredients().remove(ingredientEntity);
}
ingredientEntity.setIsHave(isHave);
ingredientRepository.save(ingredientEntity);
barEntityRepository.save(bar);
}

View File

@@ -4,14 +4,20 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.List;
import java.util.concurrent.ExecutorService;
@Slf4j
@Service
@@ -20,6 +26,8 @@ public class SessionService {
private final VisitorsRepository visitorsRepository;
private final CocktailRepository cocktailRepository;
private final BarEntityRepository barEntityRepository;
private final IngredientRepository ingredientRepository;
public Visitor getVisitor() {
Long id = ((Visitor) SecurityContextHolder.getContext()
@@ -40,4 +48,42 @@ public class SessionService {
.build())
.toList();
}
public void changeActiveBar(Long id) {
BarEntity lastBar = barEntityRepository.findByActiveTrue().orElseThrow();
lastBar.setActive(false);
barEntityRepository.save(lastBar);
lastBar.getIngredients().stream()
.peek(i -> i.setIsHave(false))
.forEach(ingredientRepository::save);
BarEntity barEntity = barEntityRepository.findById(id).orElseThrow();
barEntity.setActive(true);
barEntity.getIngredients().stream()
.peek(i -> i.setIsHave(true))
.forEach(ingredientRepository::save);
barEntityRepository.save(barEntity);
}
public List<BarResponseDto> findAllBar() {
return barEntityRepository.findAll().stream()
.map(BarResponseDto::mapToDto)
.toList();
}
public void deleteBar(Long id) {
barEntityRepository.deleteById(id);
}
public BarResponseDto createBar(String name) {
BarEntity bar = new BarEntity();
bar.setName(name);
bar.setActive(false);
bar = barEntityRepository.save(bar);
return BarResponseDto.mapToDto(bar);
}
}