package jef.database.routing.jdbc; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.Date; import java.sql.NClob; import java.sql.ParameterMetaData; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.RowId; import java.sql.SQLException; import java.sql.SQLXML; import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import jef.database.innerpool.JConnection; import jef.database.jdbc.GenerateKeyReturnOper; import jef.tools.Assert; import jef.tools.collection.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JPreparedStatement extends JStatement implements java.sql.PreparedStatement { private static final Logger log = LoggerFactory.getLogger(JPreparedStatement.class); // 准备好的原始SQL语句 private final String originalSQL; // 批处理任务 List<List<ParameterContext>> batchArgs; // executeUpdate参数 private GenerateKeyReturnOper generateKeys = GenerateKeyReturnOper.NONE; // 当前的任务参数 private Map<Integer, ParameterContext> parameterSettings = new TreeMap<Integer, ParameterContext>(); /** * 构造 * * @param sql * @param routingConnection * @param resultsetType * @param resultSetConcurrency */ public JPreparedStatement(String sql, JConnection routingConnection, int resultsetType, int resultSetConcurrency, int resultHolder) { super(routingConnection, resultsetType, resultSetConcurrency, resultHolder); this.originalSQL = sql; } public JPreparedStatement(String sql, JConnection jConnection, GenerateKeyReturnOper oper) { super(jConnection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); this.originalSQL = sql; this.generateKeys = oper; } public void clearParameters() throws SQLException { parameterSettings.clear(); } public boolean execute() throws SQLException { if (log.isDebugEnabled()) { log.debug("invoke execute, sql = " + originalSQL); } if (SqlTypeParser.isQuerySql(originalSQL)) { executeQuery(); return true; } else { executeUpdate(); return false; } } public ResultSet executeQuery() throws SQLException { return executeQueryInternal(originalSQL, toValues(this.parameterSettings)); } public int executeUpdate() throws SQLException { return executeUpdateInternal(originalSQL, generateKeys, toValues(this.parameterSettings)); } private List<ParameterContext> toValues(Map<Integer, ParameterContext> parameterSettings2) { List<ParameterContext> l = new ArrayList<ParameterContext>(); for (Entry<Integer, ParameterContext> e : parameterSettings2.entrySet()) { CollectionUtils.setElement(l, e.getKey() - 1, e.getValue()); } return l; } /** * batch 操作中,如果一个连接内的pst出现更新异常。 则整个连接的后续更新都会终止。 但其他连接的更新还会继续。 目前并不提供返回值设置。 */ public int[] executeBatch() throws SQLException { if (batchArgs == null || batchArgs.isEmpty()) { return new int[0]; } if (log.isDebugEnabled()) { log.debug("invoke executeBatch, sql = " + originalSQL); } checkClosed(); ensureResultSetIsEmpty(); return executeBatchInternal(originalSQL, generateKeys, this.batchArgs); } public void addBatch() throws SQLException { if (batchArgs == null) { batchArgs = new LinkedList<List<ParameterContext>>(); } check(parameterSettings); batchArgs.add(new ArrayList<ParameterContext>(parameterSettings.values())); parameterSettings.clear(); } private void check(Map<Integer, ParameterContext> parameterSettings2) { if (parameterSettings2.isEmpty()) return; Integer[] ints = parameterSettings2.keySet().toArray(new Integer[parameterSettings2.size()]); Assert.isTrue(ints[0] == 1); Assert.isTrue(ints[ints.length - 1] == ints.length); } // /////////////////////以下为不支持的方法///////////////////////////////////////////////////// public ResultSetMetaData getMetaData() throws SQLException { throw new UnsupportedOperationException("getMetaData"); } public ParameterMetaData getParameterMetaData() throws SQLException { throw new UnsupportedOperationException("getParameterMetaData"); } public void setRowId(int parameterIndex, RowId x) throws SQLException { throw new SQLException("not support exception"); } public void setNString(int parameterIndex, String value) throws SQLException { throw new SQLException("not support exception"); } public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { throw new SQLException("not support exception"); } public void setNClob(int parameterIndex, NClob value) throws SQLException { throw new SQLException("not support exception"); } public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { throw new SQLException("not support exception"); } public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { throw new SQLException("not support exception"); } public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { throw new SQLException("not support exception"); } public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { throw new SQLException("not support exception"); } public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { throw new SQLException("not support exception"); } public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { throw new SQLException("not support exception"); } public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { throw new SQLException("not support exception"); } public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { throw new SQLException("not support exception"); } public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { throw new SQLException("not support exception"); } public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { throw new SQLException("not support exception"); } public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { throw new SQLException("not support exception"); } public void setClob(int parameterIndex, Reader reader) throws SQLException { throw new SQLException("not support exception"); } public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { throw new SQLException("not support exception"); } public void setNClob(int parameterIndex, Reader reader) throws SQLException { throw new SQLException("not support exception"); } // //////////////////////////////设置参数/////////////////////////////////// public void setArray(int i, Array x) throws SQLException { parameterSettings.put(i, new ParameterContext(ParameterMethod.setArray, i, x)); } public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setAsciiStream, parameterIndex, x, length)); } public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBigDecimal, parameterIndex, x)); } public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBinaryStream, parameterIndex, x, length)); } public void setBlob(int i, Blob x) throws SQLException { parameterSettings.put(i, new ParameterContext(ParameterMethod.setBlob, i, x)); } public void setBoolean(int parameterIndex, boolean x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBoolean, parameterIndex, x)); } public void setByte(int parameterIndex, byte x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setByte, parameterIndex, x)); } public void setBytes(int parameterIndex, byte[] x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setBytes, parameterIndex, x)); } public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setCharacterStream, parameterIndex, reader, length)); } public void setClob(int i, Clob x) throws SQLException { parameterSettings.put(i, new ParameterContext(ParameterMethod.setClob, i, x)); } public void setDate(int parameterIndex, Date x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setDate1, parameterIndex, x)); } public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setDate2, parameterIndex, x, cal)); } public void setDouble(int parameterIndex, double x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setDouble, parameterIndex, x)); } public void setFloat(int parameterIndex, float x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setFloat, parameterIndex, x)); } public void setInt(int parameterIndex, int x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setInt, parameterIndex, x)); } public void setLong(int parameterIndex, long x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setLong, parameterIndex, x)); } public void setNull(int parameterIndex, int sqlType) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setNull1, parameterIndex, sqlType)); } public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException { parameterSettings.put(paramIndex, new ParameterContext(ParameterMethod.setNull2, paramIndex, sqlType, typeName)); } public void setObject(int parameterIndex, Object x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setObject1, parameterIndex, x)); } public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setObject2, parameterIndex, x, targetSqlType)); } public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setObject3, parameterIndex, x, targetSqlType, scale)); } public void setRef(int i, Ref x) throws SQLException { parameterSettings.put(i, new ParameterContext(ParameterMethod.setRef, i, x)); } public void setShort(int parameterIndex, short x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setShort, parameterIndex, x)); } public void setString(int parameterIndex, String x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setString, parameterIndex, x)); } public void setTime(int parameterIndex, Time x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTime1, parameterIndex, x)); } public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTime2, parameterIndex, x, cal)); } public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTimestamp1, parameterIndex, x)); } public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setTimestamp2, parameterIndex, x, cal)); } public void setURL(int parameterIndex, URL x) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setURL, parameterIndex, x)); } public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { parameterSettings.put(parameterIndex, new ParameterContext(ParameterMethod.setUnicodeStream, parameterIndex, x, length)); } }