1 16 17 package org.springframework.jdbc.core; 18 19 import java.sql.Connection ; 20 import java.sql.PreparedStatement ; 21 import java.sql.ResultSet ; 22 import java.sql.SQLException ; 23 import java.sql.Types ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 31 import org.springframework.dao.InvalidDataAccessApiUsageException; 32 import org.springframework.dao.InvalidDataAccessResourceUsageException; 33 import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; 34 import org.springframework.util.Assert; 35 36 44 public class PreparedStatementCreatorFactory { 45 46 47 private final String sql; 48 49 50 private final List declaredParameters; 51 52 private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; 53 54 private boolean updatableResults = false; 55 56 private boolean returnGeneratedKeys = false; 57 58 private String [] generatedKeysColumnNames = null; 59 60 private NativeJdbcExtractor nativeJdbcExtractor; 61 62 private String sqlToUse = null; 63 64 65 69 public PreparedStatementCreatorFactory(String sql) { 70 this.sql = sql; 71 this.declaredParameters = new LinkedList (); 72 } 73 74 79 public PreparedStatementCreatorFactory(String sql, int[] types) { 80 this.sql = sql; 81 this.declaredParameters = SqlParameter.sqlTypesToAnonymousParameterList(types); 82 } 83 84 90 public PreparedStatementCreatorFactory(String sql, List declaredParameters) { 91 this.sql = sql; 92 this.declaredParameters = declaredParameters; 93 } 94 95 96 100 public void addParameter(SqlParameter param) { 101 this.declaredParameters.add(param); 102 } 103 104 112 public void setResultSetType(int resultSetType) { 113 this.resultSetType = resultSetType; 114 } 115 116 120 public void setUpdatableResults(boolean updatableResults) { 121 this.updatableResults = updatableResults; 122 } 123 124 128 public void setReturnGeneratedKeys(boolean returnGeneratedKeys) { 129 this.returnGeneratedKeys = returnGeneratedKeys; 130 } 131 132 135 public void setGeneratedKeysColumnNames(String [] names) { 136 this.generatedKeysColumnNames = names; 137 } 138 139 143 public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { 144 this.nativeJdbcExtractor = nativeJdbcExtractor; 145 } 146 147 150 public void setSqlToUse(String sqlToUse) { 151 this.sqlToUse = sqlToUse; 152 } 153 154 155 159 public PreparedStatementSetter newPreparedStatementSetter(List params) { 160 return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST); 161 } 162 163 167 public PreparedStatementSetter newPreparedStatementSetter(Object [] params) { 168 return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.EMPTY_LIST); 169 } 170 171 175 public PreparedStatementCreator newPreparedStatementCreator(List params) { 176 return new PreparedStatementCreatorImpl(params != null ? params : Collections.EMPTY_LIST); 177 } 178 179 183 public PreparedStatementCreator newPreparedStatementCreator(Object [] params) { 184 return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.EMPTY_LIST); 185 } 186 187 193 public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object [] params) { 194 return new PreparedStatementCreatorImpl( 195 sqlToUse, params != null ? Arrays.asList(params) : Collections.EMPTY_LIST); 196 } 197 198 199 202 private class PreparedStatementCreatorImpl 203 implements PreparedStatementCreator, PreparedStatementSetter, SqlProvider, ParameterDisposer { 204 205 private final String actualSql; 206 207 private final List parameters; 208 209 public PreparedStatementCreatorImpl(List parameters) { 210 this((sqlToUse != null ? sqlToUse : sql), parameters); 211 } 212 213 public PreparedStatementCreatorImpl(String actualSql, List parameters) { 214 this.actualSql = actualSql; 215 Assert.notNull(parameters, "Parameters List must not be null"); 216 this.parameters = parameters; 217 if (this.parameters.size() != declaredParameters.size()) 218 throw new InvalidDataAccessApiUsageException( 219 "SQL [" + sql + "]: given " + this.parameters.size() + 220 " parameters but expected " + declaredParameters.size()); 221 } 222 223 public PreparedStatement createPreparedStatement(Connection con) throws SQLException { 224 PreparedStatement ps = null; 225 if (generatedKeysColumnNames != null || returnGeneratedKeys) { 226 try { 227 if (generatedKeysColumnNames != null) { 228 ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames); 229 } 230 else { 231 ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS); 232 } 233 } 234 catch (AbstractMethodError ex) { 235 throw new InvalidDataAccessResourceUsageException( 236 "The JDBC driver is not compliant to JDBC 3.0 and thus " + 237 "does not support retrieval of auto-generated keys", ex); 238 } 239 } 240 else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) { 241 ps = con.prepareStatement(this.actualSql); 242 } 243 else { 244 ps = con.prepareStatement(this.actualSql, resultSetType, 245 updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY); 246 } 247 setValues(ps); 248 return ps; 249 } 250 251 public void setValues(PreparedStatement ps) throws SQLException { 252 PreparedStatement psToUse = ps; 254 if (nativeJdbcExtractor != null) { 255 psToUse = nativeJdbcExtractor.getNativePreparedStatement(ps); 256 } 257 258 int sqlColIndx = 1; 260 for (int i = 0; i < this.parameters.size(); i++) { 261 SqlParameter declaredParameter = (SqlParameter) declaredParameters.get(i); 262 Object in = this.parameters.get(i); 263 if (in instanceof Collection && declaredParameter.getSqlType() != Types.ARRAY) { 264 Collection entries = (Collection ) in; 265 for (Iterator it = entries.iterator(); it.hasNext();) { 266 Object entry = it.next(); 267 StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, entry); 268 } 269 } 270 else { 271 StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, in); 272 } 273 } 274 } 275 276 public String getSql() { 277 return sql; 278 } 279 280 public void cleanupParameters() { 281 StatementCreatorUtils.cleanupParameters(this.parameters); 282 } 283 284 public String toString() { 285 StringBuffer buf = new StringBuffer ("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=["); 286 buf.append(sql).append("]; parameters=").append(this.parameters); 287 return buf.toString(); 288 } 289 } 290 291 } 292 | Popular Tags |