Поддержка Spring Data Java 8
1. обзор
Spring Data теперь поддерживает основные функции Java 8, такие какOptional,Stream API иCompletableFuture.
В этой быстрой статье мы рассмотрим несколько примеров того, как мы можем использовать их с фреймворком.
2. Optionalс
Начнем с методов репозитория CRUD, которые теперь оборачиваются вOptional:
public interface CrudRepository extends Repository {
Optional findById(ID id);
}
При возврате экземпляраOptional это полезный намек на то, что существует вероятность того, что значение может не существовать. Более подробную информацию о Optional можно найти вhere.
Все, что нам теперь нужно сделать, это указать тип возвращаемого значения какOptional:
public interface UserRepository extends JpaRepository {
Optional findOneByName(String name);
}
3. Stream API
Spring Data также обеспечивает поддержку одной из наиболее важных функций Java 8 - APIStream.
Раньше, когда нам нужно было возвращать более одного результата, нам нужно было возвращать коллекцию:
public interface UserRepository extends JpaRepository {
// ...
List findAll();
// ...
}
Одной из проблем этой реализации было потребление памяти.
Нам пришлось с нетерпением загружать и хранить все найденные объекты в нем.
Мы могли бы улучшить, используя пейджинг:
public interface UserRepository extends JpaRepository {
// ...
Page findAll(Pageable pageable);
// ...
}
В некоторых сценариях этого достаточно, но в других случаях разбиение на страницы - не лучший вариант из-за большого количества запросов, необходимых для получения данных.
Благодаря Java 8Stream API и провайдерам JPA - теперь мы можемdefine that our repository method returns just a Stream of objects:
public interface UserRepository extends JpaRepository {
// ...
Stream findAllByName(String name);
// ...
}
Spring Data использует реализацию, зависящую от поставщика, для потоковой передачи результата (Hibernate используетScrollableResultSet, EclipseLink используетScrollableCursor). Это уменьшает количество потребления памяти и запросов к базе данных. Из-за этого он намного быстрее, чем два упомянутых ранее решения.
Processing data with a Stream requires us to close a Stream when we finish it.
Это можно сделать, вызвав методclose() дляStream или используяtry-with-resources:
try (Stream foundUsersStream
= userRepository.findAllByName(USER_NAME_ADAM)) {
assertThat(foundUsersStream.count(), equalTo(3l));
We must also remember to call a repository method within a transaction. В противном случае мы получим исключение:
org.springframework.dao.InvalidDataAccessApiUsageException: вы пытаетесь выполнить метод потокового запроса без внешней транзакции, которая поддерживает соединение, так чтоStream может быть фактически использован. Убедитесь, что код, использующий поток, использует@Transactional или любой другой способ объявления транзакции (только для чтения).
4. CompletableFutureс
Spring Data repositories can run asynchronously with the support of Java 8’s CompletableFuture и механизм Spring для выполнения асинхронных методов:
@Async
CompletableFuture findOneByStatus(Integer status);
Клиент, который вызывает этот метод, немедленно вернет будущее, но метод продолжит выполнение в другом потоке.
Более подробную информацию об обработкеCompletableFuture можно найти вhere.
5. Заключение
В этом руководстве мы показали, как функции Java 8 работают вместе с Spring Data.
Доступна полная реализация примеровover on Github.