springs jdbctemplate可以用于查询数据库并使结果作为流提供吗?
jrcvhitl1#
是的,但不是现成的。我发现这篇关于如何做到这一点的非常有用的文章:将Java8流api与spring的jdbctemplate结合使用。受本文启发,我改进了实现:
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{@literal <T>} consumer * @param sql * @param parameters * @param clazz * @param consumer * @param <T> */ public <T> void queryForStream( String sql, MapSqlParameterSource parameters, Class<T> clazz, java.util.function.Consumer<Stream<T>> consumer ) { queryForStream(sql, parameters, resultSetStream -> { BeanPropertyRowMapper<T> mapper = new TrimmingBeanPropertyRowMapper<>(clazz); consumer.accept(resultSetStream.map(r -> mapIt(r, mapper))); return null; }); } // Build a Stream<ResultSet> private void queryForStream( String sql, MapSqlParameterSource parameters, java.util.function.UnaryOperator<Stream<ResultSet>> operator ) { jdbcTemplate.query(sql, parameters, resultSet -> { final ResultSetWrappingSqlRowSet rowSet = new ResultSetWrappingSqlRowSet(resultSet); final boolean parallel = false; Spliterator<ResultSet> spliterator = 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> T mapIt(ResultSet resultSet, BeanPropertyRowMapper<T> mapper) { try { return mapper.mapRow(resultSet, 0); } catch (SQLException e) { throw new RuntimeException(e); } } }
这就是如何在用kotlin实现的dao中使用它的方法,因为它支持多行字符串:
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<Stream<MyEntity>>) { queryStreamer.queryForStream(sql, MapSqlParameterSource(), MyEntity::class.java, consumer) } }
就这样-玩得开心:-)
1条答案
按热度按时间jrcvhitl1#
是的,但不是现成的。
我发现这篇关于如何做到这一点的非常有用的文章:将Java8流api与spring的jdbctemplate结合使用。
受本文启发,我改进了实现:
这就是如何在用kotlin实现的dao中使用它的方法,因为它支持多行字符串:
就这样-玩得开心:-)