правка поиска коктейлей - переведено на стримы
This commit is contained in:
@@ -2,8 +2,6 @@ package ru.kayashov.bar.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.query.Query;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -32,20 +30,18 @@ import ru.kayashov.bar.repository.IngredientRepository;
|
||||
import ru.kayashov.bar.repository.ReceiptRepository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Join;
|
||||
import javax.persistence.criteria.JoinType;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@@ -87,65 +83,6 @@ public class CocktailService {
|
||||
return mapper.cocktailsToDtoList(criteria(dto), false, true);
|
||||
}
|
||||
|
||||
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
|
||||
Session session = entityManager.unwrap(Session.class);
|
||||
CriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class);
|
||||
Root<CocktailEntity> root = criteriaQuery.from(CocktailEntity.class);
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
criteriaQuery.distinct(true);
|
||||
if (!dto.getAll()) {
|
||||
Predicate pr = cb.isTrue(root.get("allowed"));
|
||||
predicates.add(pr);
|
||||
}
|
||||
|
||||
if (!dto.getSearch().isEmpty()) {
|
||||
String[] search = dto.getSearch().split(" ");
|
||||
List<Predicate> in = new ArrayList<>();
|
||||
Join<CocktailEntity, ReceiptEntity> receiptJoin = root.join("receipt", JoinType.LEFT);
|
||||
for (String s : search) {
|
||||
in.add(cb.like(cb.lower(root.get("name")), "%" + s.toLowerCase() + "%"));
|
||||
in.add(cb.like(cb.lower(receiptJoin.get("ingredient").get("name")), "%" + s.toLowerCase() + "%"));
|
||||
}
|
||||
predicates.add(cb.or(in.toArray(new Predicate[0])));
|
||||
}
|
||||
|
||||
if (dto.getOnlyFavourite()) {
|
||||
predicates.add(cb.isTrue(root.get("isFavorite")));
|
||||
}
|
||||
|
||||
if (dto.getGlass() != null && !dto.getGlass().isEmpty()) {
|
||||
predicates.add(root.get("glass").in(dto.getGlass().stream().map(Glass::findValue).toList()));
|
||||
}
|
||||
|
||||
if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
|
||||
predicates.add(root.get("category").in(dto.getCategory().stream().map(Category::findValue).toList()));
|
||||
}
|
||||
|
||||
if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) {
|
||||
predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
|
||||
}
|
||||
|
||||
//todo: доделать другие виды сортировки
|
||||
Order order;
|
||||
switch (dto.getSort()) {
|
||||
case NAME_ASC -> order = cb.asc(root.get("name"));
|
||||
case NAME_DESC -> order = cb.desc(root.get("name"));
|
||||
default -> order = cb.asc(root.get("name"));
|
||||
}
|
||||
|
||||
criteriaQuery.where(predicates.toArray(new Predicate[0]))
|
||||
.orderBy(order);
|
||||
Query<CocktailEntity> query = session.createQuery(criteriaQuery);
|
||||
query.setFirstResult(dto.getPage() * dto.getSize());
|
||||
query.setMaxResults(dto.getSize());
|
||||
List<CocktailEntity> cocktailEntities = query.getResultList();
|
||||
|
||||
log.info("Найдено {} коктейлей", cocktailEntities.size());
|
||||
return cocktailEntities;
|
||||
}
|
||||
|
||||
public CocktailForListResponseDto findById(Long id) {
|
||||
CocktailEntity cocktail = repository.findById(id).orElseThrow();
|
||||
return mapper.cocktailToFullDto(cocktail);
|
||||
@@ -244,6 +181,60 @@ public class CocktailService {
|
||||
log.info("Коктейль {} - {} был скрыт для бара {} - {}", cocktail.getId(), cocktail.getName(), bar.getId(), bar.getName());
|
||||
}
|
||||
|
||||
public void drink(Long id) {
|
||||
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
|
||||
int count = cocktail.getCountDrink() + 1;
|
||||
cocktail.setCountDrink(count);
|
||||
repository.save(cocktail);
|
||||
|
||||
eventService.createEvent(Event.builder()
|
||||
.type(EventType.DRINK)
|
||||
.date(LocalDateTime.now())
|
||||
.oldState(cocktail.getName())
|
||||
.newState(String.valueOf(count))
|
||||
.build());
|
||||
}
|
||||
|
||||
//todo: написать функцию в БД, чтобы ускорить работу и сохранить читаемый код
|
||||
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
|
||||
Instant now = Instant.now();
|
||||
List<CocktailEntity> cocktails = repository.findAll()
|
||||
.stream()
|
||||
//todo: доделать другие виды сортировки
|
||||
.sorted(Comparator.comparing(CocktailEntity::getName))
|
||||
.filter(c -> c.getAllowed() || dto.getAll())
|
||||
.filter(c -> c.getIsFavorite() || !dto.getOnlyFavourite())
|
||||
.filter(c -> isEmpty(dto.getGlass()) || dto.getGlass().contains(c.getGlass().getName()))
|
||||
.filter(c -> isEmpty(dto.getCategory()) || dto.getCategory().contains(c.getCategory().getName()))
|
||||
.filter(c -> isEmpty(dto.getAlcohol()) || dto.getAlcohol().contains(c.getAlcoholic().getValue()))
|
||||
.filter(c -> dto.getSearch().isEmpty() || textSearchFilter(c, dto.getSearch()))
|
||||
.skip((long) dto.getPage() * dto.getSize())
|
||||
.limit(dto.getSize())
|
||||
.toList();
|
||||
log.info("Найдено {} коктейлей за {} ms", cocktails.size(), Duration.between(now, Instant.now()).toMillis());
|
||||
return cocktails;
|
||||
}
|
||||
|
||||
private boolean textSearchFilter(CocktailEntity cocktail, String founding) {
|
||||
String[] search = founding.split(" ");
|
||||
|
||||
if (Arrays.stream(search).anyMatch(s -> cocktail.getName().toLowerCase().contains(s.toLowerCase()))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> ingredientsNames = cocktail.getReceipt().stream()
|
||||
.map(ReceiptEntity::getIngredient)
|
||||
.map(IngredientEntity::getName)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return Arrays.stream(search).anyMatch(s -> ingredientsNames.contains(s.toLowerCase()));
|
||||
}
|
||||
|
||||
private boolean isEmpty(List<?> value) {
|
||||
return value == null || value.isEmpty();
|
||||
}
|
||||
|
||||
//todo: попробовать отыграть эту связку каскадами
|
||||
private void editCocktailReceipts(List<ReceiptEntity> old, List<ReceiptResponseDto> actual, CocktailEntity cocktail) {
|
||||
for (ReceiptResponseDto receipt : actual) {
|
||||
@@ -309,18 +300,65 @@ public class CocktailService {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void drink(Long id) {
|
||||
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
|
||||
int count = cocktail.getCountDrink() + 1;
|
||||
cocktail.setCountDrink(count);
|
||||
repository.save(cocktail);
|
||||
|
||||
eventService.createEvent(Event.builder()
|
||||
.type(EventType.DRINK)
|
||||
.date(LocalDateTime.now())
|
||||
.oldState(cocktail.getName())
|
||||
.newState(String.valueOf(count))
|
||||
.build());
|
||||
//todo: оставить до написания функции в БД
|
||||
// private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {
|
||||
// Instant now = Instant.now();
|
||||
// Session session = entityManager.unwrap(Session.class);
|
||||
// CriteriaBuilder cb = session.getCriteriaBuilder();
|
||||
// CriteriaQuery<CocktailEntity> criteriaQuery = cb.createQuery(CocktailEntity.class);
|
||||
// Root<CocktailEntity> root = criteriaQuery.from(CocktailEntity.class);
|
||||
// List<Predicate> predicates = new ArrayList<>();
|
||||
//
|
||||
// criteriaQuery.distinct(true);
|
||||
// if (!dto.getAll()) {
|
||||
// Predicate pr = cb.isTrue(root.get("allowed"));
|
||||
// predicates.add(pr);
|
||||
// }
|
||||
//
|
||||
// if (!dto.getSearch().isEmpty()) {
|
||||
// String[] search = dto.getSearch().split(" ");
|
||||
// List<Predicate> in = new ArrayList<>();
|
||||
// Join<CocktailEntity, ReceiptEntity> receiptJoin = root.join("receipt", JoinType.LEFT);
|
||||
// for (String s : search) {
|
||||
// in.add(cb.like(cb.lower(root.get("name")), "%" + s.toLowerCase() + "%"));
|
||||
// in.add(cb.like(cb.lower(receiptJoin.get("ingredient").get("name")), "%" + s.toLowerCase() + "%"));
|
||||
// }
|
||||
// predicates.add(cb.or(in.toArray(new Predicate[0])));
|
||||
// }
|
||||
//
|
||||
// if (dto.getOnlyFavourite()) {
|
||||
// predicates.add(cb.isTrue(root.get("isFavorite")));
|
||||
// }
|
||||
//
|
||||
// if (dto.getGlass() != null && !dto.getGlass().isEmpty()) {
|
||||
// predicates.add(root.get("glass").in(dto.getGlass().stream().map(Glass::findValue).toList()));
|
||||
// }
|
||||
//
|
||||
// if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
|
||||
// predicates.add(root.get("category").in(dto.getCategory().stream().map(Category::findValue).toList()));
|
||||
// }
|
||||
//
|
||||
// if (dto.getAlcohol() != null && !dto.getAlcohol().isEmpty()) {
|
||||
// predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
|
||||
// }
|
||||
|
||||
}
|
||||
// //todo: доделать другие виды сортировки
|
||||
// Order order;
|
||||
// switch (dto.getSort()) {
|
||||
// case NAME_ASC -> order = cb.asc(root.get("name"));
|
||||
// case NAME_DESC -> order = cb.desc(root.get("name"));
|
||||
// default -> order = cb.asc(root.get("name"));
|
||||
// }
|
||||
//
|
||||
// criteriaQuery.where(predicates.toArray(new Predicate[0]))
|
||||
// .orderBy(order);
|
||||
// Query<CocktailEntity> query = session.createQuery(criteriaQuery);
|
||||
// query.setFirstResult(dto.getPage() * dto.getSize());
|
||||
// query.setMaxResults(dto.getSize());
|
||||
// List<CocktailEntity> cocktailEntities = query.getResultList();
|
||||
//
|
||||
// log.info("Найдено {} коктейлей за {} ms", cocktailEntities.size(), Duration.between(now, Instant.now()).toMillis());
|
||||
// return cocktailEntities;
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user