Я думаю, что естественный способ сделать это - обработать запрос в JPA, но выполнить нумерацию и искажение строк в Java. Запрос выглядит так:
EntityManagerFactory emf;
String lang;
String keyword;
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Book> criteria = builder.createQuery(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
Поскольку результаты возвращаются в списке, вы можете просто использовать индекс в списке для поля «нет» и написать метод getContentSnippet () в Book для выполнения подстроки и замены.
Если вы действительно хотите выполнить искажение строк в базе данных, возможно, чтобы уменьшить объем передаваемого текста, тогда вы можете написать запрос кортежа, который может получить книгу и фрагмент. Обратите внимание, что я все равно получу всю книгу, а не отдельные поля, потому что это значительно облегчает последующее программирование; если вы хотите избежать передачи всего содержимого, отметьте его для отложенной загрузки в классе Book. Запрос выглядит так:
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
final Root<Book> root = criteria.from(Book.class);
final Expression<String> snippetExpr = builder.substring(root.get(Book_.content), 1, 120);
criteria.multiselect(root, snippetExpr);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
Я использую подстроку для создания фрагмента, потому что я использую PostgreSQL, и у него нет эквивалента функции SUBSTRING_INDEX. Вы можете использовать CriteriaBuilder.function для вызова его с MySQL. Я все еще не делаю нумерацию или замену в запросе, потому что я все еще думаю, что это лучше сделать в коде.
EntityManager em = emf.createEntityManager();
TypedQuery<Tuple> q = em.createQuery(criteria);
List<Tuple> booksAndSnippets = q.getResultList();
for (int i = 0; i < booksAndSnippets.size(); ++i) {
Tuple bookAndSnippet = booksAndSnippets.get(i);
int no = i + 1;
Book book = bookAndSnippet.get(root);
String snippet = bookAndSnippet.get(snippetExpr).replace("<br>", " ");
}
Я действительно думаю, что вам, возможно, будет легче использовать JPQL!