Сортировка ResultSet, полученного из SpringJpa ExampleMatcher из наиболее подходящего для наименьшего, для использования в расширенном поиске - PullRequest
0 голосов
/ 01 мая 2020

Я нахожусь в процессе написания расширенного поиска с использованием Spring boot и MySQL для системы управления книгами.

Объект My Book содержит различную информацию, такую ​​как material id,book name, author, publisher, description, product type (как в книге рассказов или справочном материале и т. Д. c.)

Мне удалось написать ExampleMatcher следующим образом;

ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny().
                withIgnoreCase()
                .withIgnorePaths("material_id")
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withStringMatcher(ExampleMatcher.StringMatcher.STARTING)
                .withIgnoreNullValues();

Example example = Example.of(book, exampleMatcher);

List<Book> all = bookRepository.findAll(example);

Но когда я получаю набор результатов, результаты сортируются в соответствии с material id. И записи, которые имеют атрибуты, совпадающие почти со всеми полями, также есть, но отсортированы по идентификатору.

Можно ли отсортировать результаты таким образом, чтобы наиболее подходящие записи были в первых нескольких записи в списке, а затем другие записи? Как, например, сортировать от наиболее подходящего к наименее подходящему?

Насколько я понял, JpaSort допускает сортировку по возрастанию и убыванию, а также мы можем разрешить указанную c сортировку для указанных c атрибутов. Но в расширенном поиске поиск выполняется динамически в соответствии с атрибутами, которые заполняет пользователь. Поэтому я не могу запрограммировать, какие поля таблицы сортировать правильно? Например, если я запрограммировал поле имени книги для сортировки в порядке возрастания и если пользователь не указал никакого значения для этого конкретного поля, то сортировка по этому полю бесполезна, верно?

Вот почему я хочу знать, есть ли способ динамической сортировки результатов от наиболее подходящего до наименее подходящего. Любой способ достижения этой цели высоко ценится. Спасибо.

1 Ответ

0 голосов
/ 02 мая 2020

После двух целых дней чтения более 50-70 статей и постов на Inte rnet я смог реализовать расширенный поиск более оптимизированным способом.

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

Обходное решение, которое я использовал, заключается в следующем. Из идеи, которую я получил, чтобы динамически генерировать запрос SQL, я смог найти руководство и ссылки на статьи по этому вопросу.

В Dynami c Запрос в Spring Boot , автор использовал Java Reflection API для ручного go через ненулевые поля класса сущности и для генерации SQL запрос. Но, как мы все знаем, когда вы используете Springboot и когда все настройки сделаны для вас Springboot, я не думаю, что это действительно эффективный способ явно иметь зависимость Hibernate, управлять сеансами и запускать SQL запрос. HibernateJpaSessionFactoryBean, использованный в приведенной выше статье, теперь устарел. Поэтому я ссылался на различные статьи и документацию Jpa-приложения Spring Data, но не смог устранить ошибку, которую я всегда получал, говоря, что Springboot не может найти bean-компонент entityManagerFactory.

Поэтому я искал способы динамически генерировать запросы, используя Spring Data JPA сам по себе и не использует Hibernate и сталкивается с хлопотами по управлению сессиями et c. Dynami c Запросы со спецификациями JPA данных Spring и Использование спецификации JPA данных Spring содержит достаточно информации о том, как реализовать JpaSpecification для динамической генерации запросов в Springboot.

Итак, в конце я использовал информацию из всех этих трех статей, размещенных здесь, чтобы придумать свою реализацию. Я использовал Java Reflection, чтобы создать Спецификацию в соответствии с типом Класса ненулевых полей в моем объекте сущности.

Новая часть, которую я добавил сам, была сгруппирована, и я сгруппировал все отдельные Спецификации вместе в Перечислите и написали al oop, чтобы динамически генерировать окончательную Спецификацию, которая будет использоваться при получении данных. Это выглядит следующим образом.

    List<BookSpecification> bookSpecifications = createDynamicQuery(book);
    if (bookSpecifications.size() != 0) {
        Specification<Book> dynamicQuery = Specification.where(bookSpecifications.get(0));

        for (int i = 1; i < bookSpecifications.size(); i++) {
            dynamicQuery = dynamicQuery.or(bookSpecifications.get(i));
        }

        List<Book> all = bookRepository.findAll(dynamicQuery);
        all.forEach(System.out::println);

        return all;
    }

Приведенный выше метод createDynamicQuery(), который я использовал по-своему, вдохновлен информацией из цитируемых статей.

Используя этот способ, я был возможность получить гораздо более точные результаты расширенного поиска вместо использования ExampleMatcher для тех же критериев расширенного поиска. И так как я ищу по заданным c именам полей, результаты поиска также были отсортированы точным образом.

...