But JDBC is still the old-school one.
Let's wrap it!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | package org.example.jdbc.stream; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; public final class StreamHelper { public static class Record { private final Map<String, Object> fields = new HashMap<>( 16 ); private final long count; private Record( final ResultSet resultSet) throws SQLException { final ResultSetMetaData metaData = resultSet.getMetaData(); count = metaData.getColumnCount(); for ( int i = 1 ; i <= count; ++i) { fields.put(metaData.getColumnName(i), resultSet.getObject(i)); } } /** * Is there a column named like this? * * @param columnName is the column name in the query. * @return True if found. */ public boolean contains( final String columnName) { return fields.containsKey(columnName); } /** * Number of columns. * * @return Numer of columns. */ public long count() { return count; } /** * Get value casted to the requested type. * <p> * No type checking happens inside. It is your job to know the datatype in the database. * <p> * Example: * {@code record.get("COLUMN1", Long.class); // returns a Long} * * @param columnName is the column name in the query. * @param type is Java type of the column. * @return The value casted to the Java type. */ public <T> T get( final String columnName, final Class<T> type) { return type.cast(getObject(columnName)); } /** * Get columns in the record. * * @return Collection of the column names. */ public Set<String> getColumns() { return Collections.unmodifiableSet(fields.keySet()); } /** * Get value as an object. * * @param columnName is the column name in the query. * @return The value. */ public Object getObject( final String columnName) { return fields.get(columnName); } /** * Get value as string. * * @param columnName is the column name in the query. * @return Value as string. */ public String getString( final String columnName) { return Objects.toString(fields.get(columnName)); } /** * Is the given cell null? * * @param columnName is the column name in the query. * @return True if null. */ public boolean isNull( final String columnName) { return getObject(columnName) == null ; } @Override public String toString() { return fields.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()) .collect(Collectors.joining( ", " )); } } /** * Wrap a ResultSet in a Stream. * <p> * The wrapper consumes the result set. The caller must close the result set after the stream * processing was finished. * * @param resultSet is the open result set to streamline. * @return A stream of rows. */ public static Stream<Record> asStream( final ResultSet resultSet) { // "est = Long.MAX_VALUE if infinite, unknown, or too expensive to compute." return StreamSupport.stream( new Spliterators.AbstractSpliterator<Record>(Long.MAX_VALUE, Spliterator.NONNULL | Spliterator.IMMUTABLE) { @Override public boolean tryAdvance( final Consumer<? super Record> action) { try { if (!resultSet.next()) { return false ; } } catch ( @SuppressWarnings ( "unused" ) final SQLException e) { return false ; } try { action.accept( new Record(resultSet)); } catch ( @SuppressWarnings ( "unused" ) final SQLException e) { return false ; } return true ; } }, true ).parallel(); } private StreamHelper() { /* Hidden. */ } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import org.example.jdbc.stream.StreamHelper; import org.example.jdbc.stream.StreamHelper.Record; // ... @GET @Path ( "test" ) public Response test() { try (Connection connection = Database.connect(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery( "SELECT * FROM MY_TABLE" )) { return Response.ok(StreamHelper.asStream(resultSet).map(Record::toString) .collect(Collectors.joining( ", " ))).build(); } catch ( final SQLException | NamingException e) { return Response.serverError().entity(e.toString()).build(); } } |
No comments :
Post a Comment