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 Evans (1.7.0 RELEASE)

новая версия 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>.