Этот вопрос не является конкретным.Я всего лишь младший разработчик, спрашивающий совета с непосильной задачей.Если это не так, как здесь, в Stackoverflow, скажите, пожалуйста.
Давайте представим, что нам нужно приложение для мониторинга правительственных сообщений.У нас есть следующая модель:
@Entity
class Message {
@Id
@Column(name = "MESSAGE_ID")
private Integer id;
@OneToMany
@JoinColumn(name = "MESSAGE_ID", referencedColumnName = "MESSAGE_ID")
private List<Dispatch> dispatches;
private String text;
//getters & setters
}
@Entity
class Dispatch {
@Id
@Column(name = "DISPATCH_ID")
private Integer id;
private String destination; //few dozen of different destinations
@OneToMany
@JoinColumn(name = "DISPATCH_ID", referencedColumnName = "DISPATCH_ID")
private List<Status> statuses;
//getters & setters
}
@Entity
class Status {
@Id
@Column(name = "STATUS_ID")
private Integer id;
private String code; //one of those: "SENT", "DELIVERED", "READ"
private Date registered;
//getters & setters
}
Контроллер и репозиторий выглядят так:
@RestController
class MessageController {
@Autowired
private MessageRepository repository;
@GetMapping("/messages")
public Page<Message> getMessagesSorted(Pageable pageable) {
return repository.findAll(pageable);
}
}
interface MessageRepository extends JpaRepository<Message, Integer> {
}
И если мы называем наш API как "../messages?size=50&page=3&sort=id, asc "мы получим именно то, что нам нужно: 4-я страница с 50 элементами, отсортированными по id.
Но следующее, что мы хотим, это отсортировать сообщения по дате, когда они были прочитаны, доставлены или отправленыконкретный пункт назначения.Например, "../messages?sort=sentToMoscow, desc"
Первой идеей является создание собственного метода в репозитории и аннотирование его с помощью @ Query.
Но будет много разныхсортировка сценариев.И что более важно, мы используем JPA Criteria API (или Spring Specification) для динамического построения других ограничений фильтрации.
Одна вещь, которую я придумал, это @Formula:
class Message {
/*
...
*/
@Formula("(select * from " +
"(select s.saved from message m " +
"join dispatch d on d.message_id = m.message_id " +
"join status s on s.dispatch_id = d.dispatch_id " +
"where m.message_id = message_id " +
"and d.destination = 'MOSCOW' and s.code = 'SENT') " +
"where rownum = 1)")
private Date sentToMoscow;
//getters & setters
}
Но это выглядитнекрасиво, даже когда он один.Если я добавлю больше, это будет катастрофа.
Итак, вопрос в том, как я могу реализовать сортировку и сохранить свою работу?