这篇文章展示了如何将java.sql.ResultSet
转换为JSON并将其流回调用方。 如果要将大型数据集从JDBC数据源以JSON格式发送到Web应用程序,此功能很有用。 流式传输使您可以一点一点地传输数据,而不必将所有数据都加载到服务器的内存中。
例如,考虑以下ResultSet
:
+---------+-----+
| name | age |
+---------+-----+
| Alice | 20 |
| Bob | 35 |
| Charles | 50 |
+---------+-----+
对应的JSON是:
[{ "name": "Alice", "age": 20 },{ "name": "Bob", "age": 35 },{ "name": "Charles", "age": 50 },
]
以下类(在我的GitHub Repository中也可用)可用于将ResultSet
转换为JSON。 请注意,此类实现Spring的ResultSetExtractor
, JdbcTemplate
可以使用该类从ResultSet
提取结果。
/*** Streams a ResultSet as JSON.*/
public class StreamingJsonResultSetExtractor implements ResultSetExtractor<Void> {private final OutputStream os;/*** @param os the OutputStream to stream the JSON to*/public StreamingJsonResultSetExtractor(final OutputStream os) {this.os = os;}@Overridepublic Void extractData(final ResultSet rs) {final var objectMapper = new ObjectMapper();try (var jg = objectMapper.getFactory().createGenerator(os, JsonEncoding.UTF8)) {writeResultSetToJson(rs, jg);jg.flush();} catch (IOException | SQLException e) {throw new RuntimeException(e);}return null;}private static void writeResultSetToJson(final ResultSet rs,final JsonGenerator jg)throws SQLException, IOException {final var rsmd = rs.getMetaData();final var columnCount = rsmd.getColumnCount();jg.writeStartArray();while (rs.next()) {jg.writeStartObject();for (var i = 1; i <= columnCount; i++) {jg.writeObjectField(rsmd.getColumnName(i), rs.getObject(i));}jg.writeEndObject();}jg.writeEndArray();}
}
要将其用于带有JAX-RS的Web服务中:
import javax.ws.rs.core.StreamingOutput;@GET
@Path("runQuery")
public StreamingOutput runQuery() {return new StreamingOutput() {@Overridepublic void write(final OutputStream os)throws IOException, WebApplicationException {jdbcTemplate.query("select name, age from person",new StreamingJsonResultSetExtractor(os));}};
}
翻译自: https://www.javacodegeeks.com/2018/09/streaming-jdbc-resultset-json.html