Java spring stream api

Can you use Springs JdbcTemplate to stream data [duplicate]

I found this very helpful article on how to do it: Using the Java 8 Stream API with Spring’s JdbcTemplate.

Inspired by this article I have made an improved implementation:

import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.stereotype.Component; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; import java.util.Spliterator; import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; @Slf4j @Component @RequiredArgsConstructor public class QueryStreamer < private final NamedParameterJdbcTemplate jdbcTemplate; /** * Execute query and make result available for a Stream> consumer * @param sql * @param parameters * @param clazz * @param consumer * @param */ public void queryForStream( String sql, MapSqlParameterSource parameters, Class clazz, java.util.function.Consumer consumer ) < queryForStream(sql, parameters, resultSetStream -> < BeanPropertyRowMappermapper = new TrimmingBeanPropertyRowMapper<>(clazz); consumer.accept(resultSetStream.map(r -> mapIt(r, mapper))); return null; >); > // Build a Stream private void queryForStream( String sql, MapSqlParameterSource parameters, java.util.function.UnaryOperator operator ) < jdbcTemplate.query(sql, parameters, resultSet -> < final ResultSetWrappingSqlRowSet rowSet = new ResultSetWrappingSqlRowSet(resultSet); final boolean parallel = false; Spliteratorspliterator = Spliterators.spliteratorUnknownSize(new Iterator<>() < @Override public boolean hasNext() < return rowSet.next(); >@Override public ResultSet next() < return resultSet; >>, Spliterator.IMMUTABLE); return operator.apply(StreamSupport.stream(spliterator, parallel)); >); > private static T mapIt(ResultSet resultSet, BeanPropertyRowMapper mapper) < try < return mapper.mapRow(resultSet, 0); >catch (SQLException e) < throw new RuntimeException(e); >> > 

And this is how you could use it in a DAO — implemented in Kotlin because of the nice multiline string literal support:

import MyEntity import QueryStreamer import org.springframework.jdbc.core.namedparam.MapSqlParameterSource import org.springframework.stereotype.Component import java.util.function.Consumer import java.util.stream.Stream @Component open class MyEntityDAO(private val queryStreamer: QueryStreamer) < val sql = """ SELECT column_1, column_2, column_3 FROM my_entity_table WHERE some_criteria = 'met' """.trimIndent() fun streamIt(consumer: Consumer>) < queryStreamer.queryForStream(sql, MapSqlParameterSource(), MyEntity::class.java, consumer) >> 

Источник

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

Spring Data теперь поддерживает основные функции Java 8, такие какOptional,Stream API иCompletableFuture.

В этой быстрой статье мы рассмотрим несколько примеров того, как мы можем использовать их с фреймворком.

2. Optionalс

Начнем с методов репозитория CRUD, которые теперь оборачиваются вOptional:

public interface CrudRepository extends Repository  < OptionalfindById(ID id); >

При возврате экземпляраOptional это полезный намек на то, что существует вероятность того, что значение может не существовать. Более подробную информацию о Optional можно найти вhere.

Все, что нам теперь нужно сделать, это указать тип возвращаемого значения какOptional:

public interface UserRepository extends JpaRepository  < OptionalfindOneByName(String name); >

3. Stream API

Spring Data также обеспечивает поддержку одной из наиболее важных функций Java 8 — APIStream.

Раньше, когда нам нужно было возвращать более одного результата, нам нужно было возвращать коллекцию:

public interface UserRepository extends JpaRepository  < // . ListfindAll(); // . >

Одной из проблем этой реализации было потребление памяти.

Нам пришлось с нетерпением загружать и хранить все найденные объекты в нем.

Мы могли бы улучшить, используя пейджинг:

public interface UserRepository extends JpaRepository  < // . PagefindAll(Pageable pageable); // . >

В некоторых сценариях этого достаточно, но в других случаях разбиение на страницы — не лучший вариант из-за большого количества запросов, необходимых для получения данных.

Благодаря Java 8Stream API и провайдерам JPA — теперь мы можемdefine that our repository method returns just a Stream of objects:

public interface UserRepository extends JpaRepository  < // . StreamfindAllByName(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.

Источник

Читайте также:  Justicemaker ru view article php
Оцените статью