mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-21 16:45:02 -05:00
Fix QueryMapper toResultSet and insertGetGeneratedKeyType to use PreparedStatementFactory and become un-ambiguous
This commit is contained in:
parent
278e99e894
commit
a490154334
@ -93,47 +93,19 @@ public class CachingQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
|
protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
|
||||||
return getPreparedStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
|
return getPreparedStatement(sql, defaultPsf);
|
||||||
}
|
|
||||||
|
|
||||||
protected PreparedStatement getPreparedStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
|
||||||
PreparedStatement ps = cache.get(sql);
|
|
||||||
if (ps == null) {
|
|
||||||
//System.out.println("cache miss");
|
|
||||||
ps = conn.prepareStatement(sql,resultSetType,resultSetConcurrency);
|
|
||||||
cache.put(sql, ps);
|
|
||||||
}
|
|
||||||
//else System.out.println("cache hit");
|
|
||||||
return ps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PreparedStatement getInsertPreparedStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
|
/**
|
||||||
|
* This could perhaps end up caching something it shouldn't, as psf could return a different PreparedStatement
|
||||||
|
* for a given sql, we are going to assume this would never happen, if it could, don't use CachingQueryMapper or
|
||||||
|
* override this method, whatever you want.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement getPreparedStatement(final String sql, final PreparedStatementFactory psf) throws SQLException {
|
||||||
PreparedStatement ps = cache.get(sql);
|
PreparedStatement ps = cache.get(sql);
|
||||||
if (ps == null) {
|
if (ps == null) {
|
||||||
//System.out.println("cache miss");
|
//System.out.println("cache miss");
|
||||||
ps = conn.prepareStatement(sql, autoGeneratedKeys);
|
ps = psf.prepareStatement(conn, sql);
|
||||||
cache.put(sql, ps);
|
|
||||||
}
|
|
||||||
//else System.out.println("cache hit");
|
|
||||||
return ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PreparedStatement getInsertPreparedStatement(final String sql, final int[] columnIndexes) throws SQLException {
|
|
||||||
PreparedStatement ps = cache.get(sql);
|
|
||||||
if (ps == null) {
|
|
||||||
//System.out.println("cache miss");
|
|
||||||
ps = conn.prepareStatement(sql, columnIndexes);
|
|
||||||
cache.put(sql, ps);
|
|
||||||
}
|
|
||||||
//else System.out.println("cache hit");
|
|
||||||
return ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PreparedStatement getInsertPreparedStatement(final String sql, final String[] columnNames) throws SQLException {
|
|
||||||
PreparedStatement ps = cache.get(sql);
|
|
||||||
if (ps == null) {
|
|
||||||
//System.out.println("cache miss");
|
|
||||||
ps = conn.prepareStatement(sql, columnNames);
|
|
||||||
cache.put(sql, ps);
|
cache.put(sql, ps);
|
||||||
}
|
}
|
||||||
//else System.out.println("cache hit");
|
//else System.out.println("cache hit");
|
||||||
@ -171,34 +143,19 @@ public class CachingQueryMapper extends QueryMapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long insertGetGeneratedKey(String sql, Object... bindObjects) throws SQLException {
|
public Long insertGetGeneratedKey(String sql, Object... bindObjects) throws SQLException {
|
||||||
return super.insertGetGeneratedKey(getInsertPreparedStatement(sql, Statement.RETURN_GENERATED_KEYS), bindObjects);
|
return super.insertGetGeneratedKey(getPreparedStatement(sql, getSingleColumnPreparedStatementFactory()), bindObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
public <T> T insertGetGeneratedKeyType(String sql, final PreparedStatementFactory psf, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
||||||
return super.insertGetGeneratedKeyType(getInsertPreparedStatement(sql, Statement.RETURN_GENERATED_KEYS), typeReference, bindObjects);
|
return super.insertGetGeneratedKeyType(getPreparedStatement(sql, psf), typeReference, bindObjects);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, int[] columnIndexes, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
|
||||||
return super.insertGetGeneratedKeyType(getInsertPreparedStatement(sql, columnIndexes), typeReference, bindObjects);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, String[] columnNames, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
|
||||||
return super.insertGetGeneratedKeyType(getInsertPreparedStatement(sql, columnNames), typeReference, bindObjects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// these grab ResultSets from the database
|
// these grab ResultSets from the database
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResultSet toResultSet(String sql, Object... bindObjects) throws SQLException {
|
|
||||||
return super.toResultSet(getPreparedStatement(sql), bindObjects);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet toResultSet(String sql, int rsType, int rsConcurrency, Object... bindObjects) throws SQLException {
|
public ResultSet toResultSet(final String sql, final PreparedStatementFactory psf, final Object... bindObjects) throws SQLException {
|
||||||
return super.toResultSet(getPreparedStatement(sql,rsType,rsConcurrency), bindObjects);
|
return super.toResultSet(getPreparedStatement(sql, psf), bindObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||||
|
@ -293,8 +293,8 @@ public class ListQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet toResultSet(String sql, int rsType, int rsConcurrency, Object... bindObjects) throws SQLException {
|
public ResultSet toResultSet(String sql, PreparedStatementFactory psf, Object... bindObjects) throws SQLException {
|
||||||
return delegate.toResultSet(prepareSql(sql, bindObjects), rsType, rsConcurrency, bindObjects);
|
return delegate.toResultSet(prepareSql(sql, bindObjects), psf, bindObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -308,13 +308,8 @@ public class ListQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, int[] columnIndexes, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
public <T> T insertGetGeneratedKeyType(String sql, PreparedStatementFactory psf, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
||||||
return delegate.insertGetGeneratedKeyType(prepareSql(sql, bindObjects), columnIndexes, typeReference, bindObjects);
|
return delegate.insertGetGeneratedKeyType(prepareSql(sql, bindObjects), psf, typeReference, bindObjects);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, String[] columnNames, TypeReference<T> typeReference, Object... bindObjects) throws SQLException {
|
|
||||||
return delegate.insertGetGeneratedKeyType(prepareSql(sql, bindObjects), columnNames, typeReference, bindObjects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh
|
||||||
|
@ -165,19 +165,9 @@ public class NullQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, int[] columnIndexes, TypeReference<T> typeReference, Object... bindObjects) {
|
public <T> T insertGetGeneratedKeyType(String sql, PreparedStatementFactory psf, TypeReference<T> typeReference, Object... bindObjects) {
|
||||||
try {
|
try {
|
||||||
return delegate.insertGetGeneratedKeyType(sql, columnIndexes, typeReference, bindObjects);
|
return delegate.insertGetGeneratedKeyType(sql, psf, typeReference, bindObjects);
|
||||||
} catch (Throwable e) {
|
|
||||||
if (verbose) e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T insertGetGeneratedKeyType(String sql, String[] columnNames, TypeReference<T> typeReference, Object... bindObjects) {
|
|
||||||
try {
|
|
||||||
return delegate.insertGetGeneratedKeyType(sql, columnNames, typeReference, bindObjects);
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (verbose) e.printStackTrace();
|
if (verbose) e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -269,9 +259,9 @@ public class NullQueryMapper extends QueryMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet toResultSet(String sql, int rsType, int rsConcurrency, Object... bindObjects) throws SQLException {
|
public ResultSet toResultSet(String sql, PreparedStatementFactory psf, Object... bindObjects) {
|
||||||
try {
|
try {
|
||||||
return delegate.toResultSet(sql, rsType, rsConcurrency, bindObjects);
|
return delegate.toResultSet(sql, psf, bindObjects);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (verbose) e.printStackTrace();
|
if (verbose) e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public interface PreparedStatementFactory {
|
||||||
|
PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException;
|
||||||
|
}
|
@ -25,7 +25,32 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
|
|
||||||
protected static final int[] ORACLE_SINGLE_COLUMN_INDEX = new int[]{1};
|
protected static final int[] ORACLE_SINGLE_COLUMN_INDEX = new int[]{1};
|
||||||
|
|
||||||
|
//IFJAVA8_START
|
||||||
|
public static final PreparedStatementFactory oracleSingleColumnPsf = (conn, sql) -> conn.prepareStatement(sql, ORACLE_SINGLE_COLUMN_INDEX);
|
||||||
|
public static final PreparedStatementFactory standardReturnGeneratedKeysPsf = (conn, sql) -> conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||||
|
public static final PreparedStatementFactory defaultPsf = Connection::prepareStatement;
|
||||||
|
//IFJAVA8_END
|
||||||
|
|
||||||
/*IFJAVA6_START
|
/*IFJAVA6_START
|
||||||
|
public static final PreparedStatementFactory oracleSingleColumnPsf = new PreparedStatementFactory() {
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {
|
||||||
|
return conn.prepareStatement(sql, ORACLE_SINGLE_COLUMN_INDEX);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final PreparedStatementFactory standardReturnGeneratedKeysPsf = new PreparedStatementFactory() {
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {
|
||||||
|
return conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public static final PreparedStatementFactory defaultPsf = new PreparedStatementFactory() {
|
||||||
|
@Override
|
||||||
|
public PreparedStatement prepareStatement(Connection conn, String sql) throws SQLException {
|
||||||
|
return conn.prepareStatement(sql);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
private static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||||
IFJAVA6_END*/
|
IFJAVA6_END*/
|
||||||
|
|
||||||
@ -332,20 +357,27 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean oracleDatabase = null;
|
private PreparedStatementFactory singleColumnPsf = null;
|
||||||
public Long insertGetGeneratedKey(final String sql, final Object... bindObjects) throws SQLException {
|
protected PreparedStatementFactory getSingleColumnPreparedStatementFactory() {
|
||||||
// this single function is somewhat database specific
|
// this single function is somewhat database specific
|
||||||
// sqlite/ms-sql/mysql works with either Statement.RETURN_GENERATED_KEYS or int[]{1}
|
// sqlite/ms-sql/mysql works with either Statement.RETURN_GENERATED_KEYS or int[]{1}
|
||||||
// oracle requires int[]{1} instead, failing on Statement.RETURN_GENERATED_KEYS
|
// oracle requires int[]{1} instead, failing on Statement.RETURN_GENERATED_KEYS
|
||||||
// postgre requires Statement.RETURN_GENERATED_KEYS instead, failing on int[]{1}
|
// postgre requires Statement.RETURN_GENERATED_KEYS instead, failing on int[]{1}
|
||||||
|
|
||||||
// so we lazily cache oracleDatabase just in this one function
|
// so we lazily cache oracleDatabase just in this one function
|
||||||
if(oracleDatabase == null)
|
if(singleColumnPsf == null) {
|
||||||
oracleDatabase = OptimalInList.isWrapperFor(conn, OptimalInList.oracleConnection);
|
if(OptimalInList.isWrapperFor(conn, OptimalInList.oracleConnection))
|
||||||
|
singleColumnPsf = oracleSingleColumnPsf;
|
||||||
|
else
|
||||||
|
singleColumnPsf = standardReturnGeneratedKeysPsf;
|
||||||
|
}
|
||||||
|
return singleColumnPsf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long insertGetGeneratedKey(final String sql, final Object... bindObjects) throws SQLException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
ps = oracleDatabase ? conn.prepareStatement(sql, ORACLE_SINGLE_COLUMN_INDEX) : conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
ps = getSingleColumnPreparedStatementFactory().prepareStatement(conn, sql);
|
||||||
return this.insertGetGeneratedKey(ps, bindObjects);
|
return this.insertGetGeneratedKey(ps, bindObjects);
|
||||||
} finally {
|
} finally {
|
||||||
tryClose(ps);
|
tryClose(ps);
|
||||||
@ -353,29 +385,13 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> T insertGetGeneratedKeyType(final String sql, final TypeReference<T> typeReference, final Object... bindObjects) throws SQLException {
|
public <T> T insertGetGeneratedKeyType(final String sql, final TypeReference<T> typeReference, final Object... bindObjects) throws SQLException {
|
||||||
PreparedStatement ps = null;
|
return insertGetGeneratedKeyType(sql, standardReturnGeneratedKeysPsf, typeReference, bindObjects);
|
||||||
try {
|
|
||||||
ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
|
||||||
return this.insertGetGeneratedKeyType(ps, typeReference, bindObjects);
|
|
||||||
} finally {
|
|
||||||
tryClose(ps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T insertGetGeneratedKeyType(final String sql, final int[] columnIndexes, final TypeReference<T> typeReference, final Object... bindObjects) throws SQLException {
|
public <T> T insertGetGeneratedKeyType(final String sql, final PreparedStatementFactory psf, final TypeReference<T> typeReference, final Object... bindObjects) throws SQLException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
ps = conn.prepareStatement(sql, columnIndexes);
|
ps = psf.prepareStatement(conn, sql);
|
||||||
return this.insertGetGeneratedKeyType(ps, typeReference, bindObjects);
|
|
||||||
} finally {
|
|
||||||
tryClose(ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T insertGetGeneratedKeyType(final String sql, final String[] columnNames, final TypeReference<T> typeReference, final Object... bindObjects) throws SQLException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
try {
|
|
||||||
ps = conn.prepareStatement(sql, columnNames);
|
|
||||||
return this.insertGetGeneratedKeyType(ps, typeReference, bindObjects);
|
return this.insertGetGeneratedKeyType(ps, typeReference, bindObjects);
|
||||||
} finally {
|
} finally {
|
||||||
tryClose(ps);
|
tryClose(ps);
|
||||||
@ -422,17 +438,17 @@ public class QueryMapper implements JdbcMapper {
|
|||||||
return bindExecute(ps, bindObjects);
|
return bindExecute(ps, bindObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet toResultSet(String sql, final Object... bindObjects) throws SQLException {
|
public ResultSet toResultSet(final String sql, final Object... bindObjects) throws SQLException {
|
||||||
return toResultSet(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, bindObjects);
|
return toResultSet(sql, defaultPsf, bindObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultSet toResultSet(String sql, int rsType, int rsConcurrency, final Object... bindObjects) throws SQLException {
|
public ResultSet toResultSet(final String sql, final PreparedStatementFactory psf, final Object... bindObjects) throws SQLException {
|
||||||
// works with StatementClosingResultSet
|
// works with StatementClosingResultSet
|
||||||
boolean error = true;
|
boolean error = true;
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
ps = conn.prepareStatement(sql, rsType, rsConcurrency);
|
ps = psf.prepareStatement(conn, sql);
|
||||||
rs = this.toResultSet(ps, bindObjects);
|
rs = this.toResultSet(ps, bindObjects);
|
||||||
error = false;
|
error = false;
|
||||||
return new StatementClosingResultSet(rs, ps);
|
return new StatementClosingResultSet(rs, ps);
|
||||||
|
Loading…
Reference in New Issue
Block a user