Поддержка Spring Data Java 8

Поддержка 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.