Все это происходит в проекте на базе Spring Boot 2, DB - PostgreSQL.
Есть лист идентификаторов вложенных сущностей(устройств) и фильтр на основе спецификации, нужно принять в GET лист этих идентификаторов и фильтр, собственно, отфильтровать таблицу в базе на основе этих параметров и выдать список записей по этим параметрам.
Пример сущности:
@Entity
@Table
public class DeviceEvent{
@ManyToOne
private User admin;
@ManyToOne
private Device device;
@Column
private TaskObject.Type type;
@Column
private Integer result;
@Column
private Date added;
@Column
private Date updated;
@Column(name = "icursor")
private Long cursor;
@ManyToOne
private City city;
@ManyToOne
private District district;
@Column
private String text;
}
Пример спецификации:
public class DeviceEventsSpec {
public static Specification<Query> find(DeviceEventsFilter deviceEventsFilter) {
return (root, query, cb) -> {
final Collection<Predicate> predicates = new ArrayList<>();
if (deviceEventsFilter.getType() != null) {
predicates.add(cb.equal(root.get("type"), deviceEventsFilter.getType()));
}
if (deviceEventsFilter.getCompany() != null){
predicates.add(cb.equal(root.get("company"), deviceEventsFilter.getCompany()));
}
if (deviceEventsFilter.getCity() != null){
predicates.add(cb.equal(root.get("city"), deviceEventsFilter.getCity()));
}
if (deviceEventsFilter.getDistrict() != null){
predicates.add(cb.equal(root.get("district"), deviceEventsFilter.getDistrict()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
}
}
Пример контроллера:
@RestController("devicesEvents")
@RequestMapping("/devices/events")
public class Events extends Base {
@Autowired
DeviceEventsRepo queryRepo;
@ApiOperation(value = "Поиск событий по фильтрам", response = Query.class)
@GetMapping("find")
public Page<Query> find(List<Long> devices, Pageable pageable, DeviceEventsFilter de
viceEventsFilter) {
if(getUser().getRole() != User.Role.ADMIN) {
deviceEventsFilter.setCompany(getUser().getCompany());
if(getUser().getCity() != null) {
deviceEventsFilter.setCity(getUser().getCity());
}
if(getUser().getDistrict() != null) {
deviceEventsFilter.setDistrict(getUser().getDistrict());
}
}
return queryRepo.findAll(DeviceEventsSpec.find(deviceEventsFilter), pageable);
}
}
в конце концов помогла такая штука, как комбинирование предикатов.
https://www.baeldung.com/jpa-and-or-criteria-predicates
Изменить немного кода в спецификации и готово)
public class DeviceEventsSpec {
public static Specification<Query> find(DeviceEventsFilter deviceEventsFilter, List<Device> devices) {
return (root, query, cb) -> {
Collection<Predicate> finalPredicates = new ArrayList<>();
final Collection<Predicate> predicates = new ArrayList<>();
if (deviceEventsFilter.getType() != null) {
predicates.add(cb.equal(root.get("type"), deviceEventsFilter.getType()));
}
if (deviceEventsFilter.getCompany() != null){
predicates.add(cb.equal(root.get("company"), deviceEventsFilter.getCompany()));
}
if (deviceEventsFilter.getCity() != null){
predicates.add(cb.equal(root.get("city"), deviceEventsFilter.getCity()));
}
if (deviceEventsFilter.getDistrict() != null){
predicates.add(cb.equal(root.get("district"), deviceEventsFilter.getDistrict()));
}
if (deviceEventsFilter.getAdded() != null){
Calendar calendar = Calendar.getInstance();
calendar.setTime(deviceEventsFilter.getAdded());
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Calendar calendarEnd = (Calendar) calendar.clone();
calendarEnd.setTime(deviceEventsFilter.getAdded());
calendarEnd.set(Calendar.HOUR, 23);
calendarEnd.set(Calendar.MINUTE, 59);
calendarEnd.set(Calendar.SECOND, 59);
predicates.add(cb.greaterThanOrEqualTo(root.get("added"), calendar.getTime()));
predicates.add(cb.lessThanOrEqualTo(root.get("added"), calendarEnd.getTime()));
}
Predicate predicate = cb.and(predicates.toArray(new Predicate[predicates.size()]));
if (devices != null){
if (devices.size() != 0) {
for (Device device : devices) {
deviceEventsFilter.setDevice(device);
Predicate predicate1 = cb.equal(root.get("device"), deviceEventsFilter.getDevice());
finalPredicates.add(cb.and(predicate, predicate1));
}
return cb.or(finalPredicates.toArray(new Predicate[finalPredicates.size()]));
}
} else if (deviceEventsFilter.getDevice() != null){
predicates.add(cb.equal(root.get("device"), deviceEventsFilter.getDevice()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть ключ зашифрованный Triple DES на C# 16 байтНеобходимо расшифровать в коде написанном на Java, но Triple DES на java из документации следует:
У меня есть объекты рассылки, в которых есть параметр времениВ это время они должны быть отправлены на e-mail пользователям
изучаю принципы REST, остановился на обновлении сущностиНе могу понять, как в сущность передать поля, которые передаю в запросе и затем обновить...