SetMaxResults для аннотации Spring -Data-JPA?
Я пытаюсь включить Spring-Data-JPA в свой проект. Одна вещь, которая смущает меня, - как мне добиться setMaxResults (n) с помощью аннотации?
например, мой код:
public interface UserRepository extends CrudRepository<User , Long>
{
@Query(value="From User u where u.otherObj = ?1 ")
public User findByOhterObj(OtherObj otherObj);
}
Мне нужно только вернуть one (and only one)
пользователя из otherObj, но я не могу найти способ аннотировать maxResults. Может кто-нибудь дать мне подсказку?
(MySQL жалуется:
[email protected]: select user0_.id as id100_, user0_.created as created100_ from User user0_ where user0_.id=2 limit ** NOT SPECIFIED **
WARN util.JDBCExceptionReporter - SQL Error: 0, SQLState: 07001
ERROR util.JDBCExceptionReporter - No value specified for parameter 2
)
Я нашел ссылку: https://jira.springsource.org/browse/DATAJPA-147, я пытался, но не получилось. Кажется, сейчас это невозможно? Почему такая важная функция не встроена в Spring-Data?
Если я реализую эту функцию вручную:
public class UserRepositoryImpl implements UserRepository
Я должен реализовать множество предопределенных методов в CrudRepository
, это было бы ужасно.
окружение: spring-3.1, spring-data-jpa-1.0.3.RELEASE.jar, spring-data-commons-core-1.1.0.RELEASE.jar
Ответы
Ответ 1
По состоянию на Spring Data JPA 1.7.0 (выпуск Эванса).
Вы можете использовать недавно введенные ключевые слова Top
и First
которые позволяют вам определять методы запроса следующим образом:
findTop10ByLastnameOrderByFirstnameAsc(String lastname);
Spring Data автоматически ограничит результаты указанным вами числом (по умолчанию 1, если не указано). Обратите внимание, что здесь упорядочение результатов становится актуальным (либо с помощью предложения OrderBy
, как показано в примере, либо путем передачи параметра Sort
в метод). Подробнее об этом читайте в блоге, посвященном новым функциям выпуска релиза Spring Data Evans, или в документации.
Для предыдущих версий
Для извлечения только фрагментов данных Spring Data использует абстракцию нумерации страниц, которая поставляется с интерфейсом Pageable
на запрашивающей стороне, а также абстракцию Page
на стороне результатов. Таким образом, вы могли бы начать с
public interface UserRepository extends Repository<User, Long> {
List<User> findByUsername(String username, Pageable pageable);
}
и используйте это так:
Pageable topTen = new PageRequest(0, 10);
List<User> result = repository.findByUsername("Matthews", topTen);
Если вам нужно знать контекст результата (какая это на самом деле страница? Это первая? Сколько всего?), Используйте Page
качестве возвращаемого типа:
public interface UserRepository extends Repository<User, Long> {
Page<User> findByUsername(String username, Pageable pageable);
}
Затем клиентский код может сделать что-то вроде этого:
Pageable topTen = new PageRequest(0, 10);
Page<User> result = repository.findByUsername("Matthews", topTen);
Assert.assertThat(result.isFirstPage(), is(true));
Не то чтобы мы запустили проекцию подсчета фактического запроса, который будет выполнен, если вы используете Page
качестве возвращаемого типа, так как нам нужно выяснить, сколько всего элементов в общей сложности для вычисления метаданных. Кроме того, убедитесь, что вы действительно оснастили PageRequest
информацией для сортировки, чтобы получить стабильные результаты. В противном случае вы можете запустить запрос дважды и получить другие результаты, даже если данные не изменились.
Ответ 2
Если вы используете Java 8 и Spring Data 1.7.0, вы можете использовать методы по умолчанию, если хотите объединить аннотацию @Query
с настройкой максимальных результатов:
public interface UserRepository extends PagingAndSortingRepository<User,Long> {
@Query("from User u where ...")
List<User> findAllUsersWhereFoo(@Param("foo") Foo foo, Pageable pageable);
default List<User> findTop10UsersWhereFoo(Foo foo) {
return findAllUsersWhereFoo(foo, new PageRequest(0,10));
}
}
Ответ 3
Существует способ, которым вы можете предоставить эквивалент "setMaxResults (n) путем аннотации", как показано ниже:
public interface ISomething extends JpaRepository<XYZ, Long>
{
@Query("FROM XYZ a WHERE a.eventDateTime < :before ORDER BY a.eventDateTime DESC")
List<XYZ> findXYZRecords(@Param("before") Date before, Pageable pageable);
}
Это должно сделать трюк, когда в качестве параметра отправляется страница.
Например, чтобы получить первые 10 записей, вам нужно установить для страницы значение этого значения:
new PageRequest(0, 10)
Ответ 4
новая версия Spring Data JPA с другим списком модулей, называемая Evans, имеет функцию использования ключевых слов Top20
и First
для ограничить результат запроса,
чтобы вы могли написать
List<User> findTop20ByLastname(String lastname, Sort sort);
или
List<User> findTop20ByLastnameOrderByIdDesc(String lastname);
или для одного результата
List<User> findFirstByLastnameOrderByIdDesc(String lastname);
Ответ 5
Лучший выбор для меня - это собственный запрос:
@Query(value="SELECT * FROM users WHERE other_obj = ?1 LIMIT 1", nativeQuery = true)
User findByOhterObj(OtherObj otherObj);
Ответ 6
Это также возможно с помощью @QueryHints. Пример bellow использует org.eclipse.persistence.config.QueryHints # JDBC_MAX_ROWS
@Query("SELECT u FROM User u WHERE .....")
@QueryHints(@QueryHint(name = JDBC_MAX_ROWS, value = "1"))
Voter findUser();
Ответ 7
Если ваш класс @Repository
extends JpaRepository
, вы можете использовать приведенный ниже пример.
int limited = 100;
Pageable pageable = new PageRequest(0,limited);
Page<Transaction> transactionsPage = transactionRepository.findAll(specification, pageable);
return transactionsPage.getContent();
getContent возвращает a List<Transaction>
.