Можно ли создать собственный запрос во время выполнения в Spring Boot?

1

Это то, что я пытаюсь сделать,

У меня есть сущность,

@Entity
public class JobEntity {

    @Id
    @GeneratedValue
    private Long id;

    @Enumerated(EnumType.STRING)
    private Project project;

    @Enumerated(EnumType.STRING)
    private JobType jobType;

    @Enumerated(EnumType.STRING)
    private JobStatus jobStatus;

    private Date createTime;
}

Я знаю, что могу настроить один запрос в репозитории, но это всего лишь один фиксированный запрос. Я надеюсь экспортировать некоторые RESTful api, как показано ниже,

/search?project=""&jobType=""&jobStatue=""&createTime=""

Эти параметры не должны быть принудительными и могут легко использовать любой из них для выполнения запроса, например

/search?createTime=""...

Есть ли элегантный способ реализовать это?

  • 0
    Есть много способов. Один хороший - с критериями api, как предполагается g00glen00b. Другим может быть создание пользовательской реализации репозитория и использование jdbctemplate для получения результата на основе входных параметров.
Теги:
spring-boot
spring
rest
spring-data-jpa

2 ответа

2
Лучший ответ

Вы можете работать со спецификационным API Spring, который является оболочкой API-критериев критериев JPA. Убедитесь, что ваш репозиторий простирается от JpaSpecificationExecutor<JobEntity>

Пример спецификации:

public class JobEntitySpecifications {
    public static Specification<JobEntity> withProject(Project project) {
        if (project == null) {
            return null;
        } else {
            return (root, query, cb) -> cb.equal(root.get("project"), project);
        }
    }

    public static Specification<JobEntity> withJobType() { ... }
    public static Specification<JobEntity> withJobStatus() { ... }
    public static Specification<JobEntity> withCreateTime() { ... }
}

Убедитесь, что вы возвращаете null, когда не указан код проекта/тип задания /..., чтобы он был проигнорирован в вашем запросе.

Теперь вы можете использовать это:

repository.findAll(Specifications.where(JobEntitySpecifications.withJobType(jobType))
    .and(JobEntitySpecifications.withJobStatus(jobStatus))
    .and(JobEntitySpecifications.withProject(project))
    .and(JobEntitySpecifications.withCreateTime(createTime)));

Вы можете сделать его еще лучше, если здесь используется статический импорт.

  • 0
    это прекрасно работает! Спасибо
0

Хотя он не уверен в динамическом построении запроса, подумайте, что съел бы время для создания запроса с помощью разных механизмов.

Существует Elastic Search, который помогает в создании такого.

Один из способов - по умолчанию задать значения запроса. Поскольку остальные значения являются перечислениями, вы можете добавить еще один литерал перечисления в каждое перечисление как ALL

что-то вроде Project.ALL, JobType.ALL, JobStatus.ALL. Внутренние статические методы в перечислении должны быть записаны как таковые, когда ВСЕ запрашивается, затем добавьте все JobTypes/Project/JobStatus в список.

Единый стандартный запрос, который может быть написан вместо запроса запроса на лету. Это легко для API с точки зрения кэширования результата запроса.

Большинство RESTful API для поиска, таких как /search?project=""&jobType=""&jobStatus=""&createTime="", работают по умолчанию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню