diff options
Diffstat (limited to 'base/src/main/java/bjc/utils/misc/BoundPreparedStatement.java')
| -rw-r--r-- | base/src/main/java/bjc/utils/misc/BoundPreparedStatement.java | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/misc/BoundPreparedStatement.java b/base/src/main/java/bjc/utils/misc/BoundPreparedStatement.java new file mode 100644 index 0000000..f87f4ec --- /dev/null +++ b/base/src/main/java/bjc/utils/misc/BoundPreparedStatement.java @@ -0,0 +1,456 @@ +package bjc.utils.misc; + +import java.math.BigDecimal; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Parent class for {@link NamedPreparedStatement} + * + * Used mostly for cases where you want to prepare the bindings independently of the actual query. + */ +public class BoundPreparedStatement { + protected final Map<String, Binder> singles = new HashMap<>(); + protected final Map<String, List<Binder>> lists = new HashMap<>(); + protected final List<ParamSnapshot> batch = new ArrayList<>(); + + private static List<Binder> toBinders(Collection<?> values, int sqlType, boolean forceType) { + ArrayList<Binder> list = new ArrayList<>(values.size()); + for (Object v : values) { + final Object val = v; + if (forceType) { + list.add((ps, i) -> { + if (val == null) + ps.setNull(i, sqlType); + else + ps.setObject(i, val, sqlType); + }); + } else { + list.add((ps, i) -> ps.setObject(i, val)); + } + } + return list; + } + + /** + * Record the current set of parameters as a batch and start a new one. + * + * @return The prepared statement + */ + public BoundPreparedStatement addBatch() { + batch.add(new ParamSnapshot(new HashMap<>(singles), deepCopyLists(lists))); + return this; + } + + /** + * Clear the currently bound parameters. + * + * @return The prepared statement + */ + public BoundPreparedStatement clearParameters() { + singles.clear(); + lists.clear(); + return this; + } + + /** + * Bind a object as a parameter + * + * @param name The name of the parameter + * @param value The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setObject(String name, Object value) { + singles.put(name, (ps, i) -> ps.setObject(i, value)); + return this; + } + + /** + * Bind a object as a parameter + * + * @param name The name of the parameter + * @param value The value for the parameter + * @param sqlType The SQL type for the parameter (see {@link java.sql.Types}) + * @return The prepared statement + */ + public BoundPreparedStatement setObject(String name, Object value, int sqlType) { + singles.put(name, (ps, i) -> { + if (value == null) + ps.setNull(i, sqlType); + else + ps.setObject(i, value, sqlType); + }); + return this; + } + + /** + * Bind a null as a parameter + * + * @param name The name of the parameter + * @param sqlType The SQL type for the parameter (see {@link java.sql.Types}) + * @return The prepared statement + */ + public BoundPreparedStatement setNull(String name, int sqlType) { + singles.put(name, (ps, i) -> ps.setNull(i, sqlType)); + return this; + } + + /** + * Bind a boolean as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setBoolean(String n, boolean x) { + singles.put(n, (ps, i) -> ps.setBoolean(i, x)); + return this; + } + + /** + * Bind a byte as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setByte(String n, byte x) { + singles.put(n, (ps, i) -> ps.setByte(i, x)); + return this; + } + + /** + * Bind a short as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setShort(String n, short x) { + singles.put(n, (ps, i) -> ps.setShort(i, x)); + return this; + } + + /** + * Bind a int as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setInt(String n, int x) { + singles.put(n, (ps, i) -> ps.setInt(i, x)); + return this; + } + + /** + * Bind a long as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setLong(String n, long x) { + singles.put(n, (ps, i) -> ps.setLong(i, x)); + return this; + } + + /** + * Bind a float as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setFloat(String n, float x) { + singles.put(n, (ps, i) -> ps.setFloat(i, x)); + return this; + } + + /** + * Bind a double as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setDouble(String n, double x) { + singles.put(n, (ps, i) -> ps.setDouble(i, x)); + return this; + } + + /** + * Bind a {@link BigDecimal} as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setBigDecimal(String n, BigDecimal x) { + singles.put(n, (ps, i) -> ps.setBigDecimal(i, x)); + return this; + } + + /** + * Bind a string as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setString(String n, String x) { + singles.put(n, (ps, i) -> ps.setString(i, x)); + return this; + } + + /** + * Bind a byte-array as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setBytes(String n, byte[] x) { + singles.put(n, (ps, i) -> ps.setBytes(i, x)); + return this; + } + + /** + * Bind a date as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setDate(String n, Date x) { + singles.put(n, (ps, i) -> ps.setDate(i, x)); + return this; + } + + /** + * Bind a date as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @param c The calendar for the date + * @return The prepared statement + */ + public BoundPreparedStatement setDate(String n, Date x, Calendar c) { + singles.put(n, (ps, i) -> ps.setDate(i, x, c)); + return this; + } + + /** + * Bind a time-value as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setTime(String n, Time x) { + singles.put(n, (ps, i) -> ps.setTime(i, x)); + return this; + } + + /** + * Bind a time-value as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @param c The calendar for the time + * @return The prepared statement + */ + public BoundPreparedStatement setTime(String n, Time x, Calendar c) { + singles.put(n, (ps, i) -> ps.setTime(i, x, c)); + return this; + } + + /** + * Bind a timestamp as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setTimestamp(String n, Timestamp x) { + singles.put(n, (ps, i) -> ps.setTimestamp(i, x)); + return this; + } + + /** + * Bind a timestamp as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @param c The calendar for the timestamp + * @return The prepared statement + */ + public BoundPreparedStatement setTimestamp(String n, Timestamp x, Calendar c) { + singles.put(n, (ps, i) -> ps.setTimestamp(i, x, c)); + return this; + } + + /** + * Bind a {@link Array} as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setArray(String n, Array x) { + singles.put(n, (ps, i) -> ps.setArray(i, x)); + return this; + } + + /** + * Bind a {@link Blob} as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setBlob(String n, Blob x) { + singles.put(n, (ps, i) -> ps.setBlob(i, x)); + return this; + } + + /** + * Bind a {@link Clob} as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setClob(String n, Clob x) { + singles.put(n, (ps, i) -> ps.setClob(i, x)); + return this; + } + + /** + * Bind a URL as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @return The prepared statement + */ + public BoundPreparedStatement setURL(String n, java.net.URL x) { + singles.put(n, (ps, i) -> ps.setURL(i, x)); + return this; + } + + /** + * Bind a ASCII stream as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @param len The length of the stream + * @return The prepared statement + */ + public BoundPreparedStatement setAsciiStream(String n, java.io.InputStream x, int len) { + singles.put(n, (ps, i) -> ps.setAsciiStream(i, x, len)); + return this; + } + + /** + * Bind a binary stream as a parameter + * + * @param n The name of the parameter + * @param x The value for the parameter + * @param len The length of the stream + * @return The prepared statement + */ + public BoundPreparedStatement setBinaryStream(String n, java.io.InputStream x, int len) { + singles.put(n, (ps, i) -> ps.setBinaryStream(i, x, len)); + return this; + } + + /** + * Bind a character stream as a parameter + * + * @param n The name of the parameter + * @param r The value for the parameter + * @param len The length of the stream + * @return The prepared statement + */ + public BoundPreparedStatement setCharacterStream(String n, java.io.Reader r, int len) { + singles.put(n, (ps, i) -> ps.setCharacterStream(i, r, len)); + return this; + } + + /** + * Bind a list parameter to the statement + * + * @param name The name of the list parameter + * @param values The values for the list parameter + * @return The prepared statement + */ + public BoundPreparedStatement setList(String name, Collection<?> values) { + lists.put(name, toBinders(values, Types.OTHER, false)); + return this; + } + + /** + * Bind a list parameter to the statement + * + * @param name The name of the list parameter + * @param values The values for the list parameter + * @return The prepared statement + */ + public BoundPreparedStatement setList(String name, Object... values) { + lists.put(name, toBinders(Arrays.asList(values), Types.OTHER, false)); + return this; + } + + /** + * Explicit SQL type for all elements (useful if nulls might appear). + * + * @param name The name of the list parameter + * @param sqlType The SQL type for the parameters + * @param values The values for the list parameter + * @return The prepared statement + */ + public BoundPreparedStatement setList(String name, int sqlType, Collection<?> values) { + lists.put(name, toBinders(values, sqlType, true)); + return this; + } + + /** + * Explicit SQL type for all elements (useful if nulls might appear). + * + * @param name The name of the list parameter + * @param sqlType The SQL type for the parameters + * @param values The values for the list parameter + * @return The prepared statement + */ + public BoundPreparedStatement setList(String name, int sqlType, Object... values) { + lists.put(name, toBinders(Arrays.asList(values), sqlType, true)); + return this; + } + + private static Map<String, List<Binder>> deepCopyLists(Map<String, List<Binder>> src) { + Map<String, List<Binder>> m = new HashMap<>(src.size()); + for (Map.Entry<String, List<Binder>> e : src.entrySet()) { + m.put(e.getKey(), new ArrayList<>(e.getValue())); + } + return m; + } + + /** + * Create a new {@link BoundPreparedStatement} + */ + public BoundPreparedStatement() { + + } +}
\ No newline at end of file |
