1 16 17 package org.springframework.jdbc.object; 18 19 import java.sql.ResultSet ; 20 import java.sql.Types ; 21 import java.util.Iterator ; 22 import java.util.LinkedList ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import javax.sql.DataSource ; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 31 import org.springframework.beans.factory.InitializingBean; 32 import org.springframework.dao.InvalidDataAccessApiUsageException; 33 import org.springframework.jdbc.core.JdbcTemplate; 34 import org.springframework.jdbc.core.ResultSetSupportingSqlParameter; 35 import org.springframework.jdbc.core.SqlParameter; 36 37 63 public abstract class RdbmsOperation implements InitializingBean { 64 65 protected final Log logger = LogFactory.getLog(getClass()); 66 67 68 private JdbcTemplate jdbcTemplate = new JdbcTemplate(); 69 70 private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; 71 72 private boolean updatableResults = false; 73 74 private boolean returnGeneratedKeys = false; 75 76 private String [] generatedKeysColumnNames = null; 77 78 79 private String sql; 80 81 82 private List declaredParameters = new LinkedList (); 83 84 89 private boolean compiled; 90 91 92 98 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 99 if (jdbcTemplate == null) { 100 throw new IllegalArgumentException ("jdbcTemplate must not be null"); 101 } 102 this.jdbcTemplate = jdbcTemplate; 103 } 104 105 108 public JdbcTemplate getJdbcTemplate() { 109 return jdbcTemplate; 110 } 111 112 116 public void setDataSource(DataSource dataSource) { 117 this.jdbcTemplate.setDataSource(dataSource); 118 } 119 120 128 public void setFetchSize(int fetchSize) { 129 this.jdbcTemplate.setFetchSize(fetchSize); 130 } 131 132 139 public void setMaxRows(int maxRows) { 140 this.jdbcTemplate.setMaxRows(maxRows); 141 } 142 143 150 public void setQueryTimeout(int queryTimeout) { 151 this.jdbcTemplate.setQueryTimeout(queryTimeout); 152 } 153 154 162 public void setResultSetType(int resultSetType) { 163 this.resultSetType = resultSetType; 164 } 165 166 169 public int getResultSetType() { 170 return resultSetType; 171 } 172 173 178 public void setUpdatableResults(boolean updatableResults) { 179 if (isCompiled()) { 180 throw new InvalidDataAccessApiUsageException( 181 "The updateableResults flag must be set before the operation is compiled"); 182 } 183 this.updatableResults = updatableResults; 184 } 185 186 189 public boolean isUpdatableResults() { 190 return updatableResults; 191 } 192 193 198 public void setReturnGeneratedKeys(boolean returnGeneratedKeys) { 199 if (isCompiled()) { 200 throw new InvalidDataAccessApiUsageException( 201 "The returnGeneratedKeys flag must be set before the operation is compiled"); 202 } 203 this.returnGeneratedKeys = returnGeneratedKeys; 204 } 205 206 210 public boolean isReturnGeneratedKeys() { 211 return returnGeneratedKeys; 212 } 213 214 218 public void setGeneratedKeysColumnNames(String [] names) { 219 if (isCompiled()) { 220 throw new InvalidDataAccessApiUsageException( 221 "The column names for the generated keys must be set before the operation is compiled"); 222 } 223 this.generatedKeysColumnNames = names; 224 } 225 226 229 public String [] getGeneratedKeysColumnNames() { 230 return generatedKeysColumnNames; 231 } 232 233 236 public void setSql(String sql) { 237 this.sql = sql; 238 } 239 240 245 public String getSql() { 246 return sql; 247 } 248 249 258 public void setTypes(int[] types) throws InvalidDataAccessApiUsageException { 259 if (isCompiled()) { 260 throw new InvalidDataAccessApiUsageException("Cannot add parameters once query is compiled"); 261 } 262 if (types != null) { 263 for (int i = 0; i < types.length; i++) { 264 declareParameter(new SqlParameter(types[i])); 265 } 266 } 267 } 268 269 276 public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException { 277 if (isCompiled()) { 278 throw new InvalidDataAccessApiUsageException("Cannot add parameters once query is compiled"); 279 } 280 this.declaredParameters.add(param); 281 } 282 283 286 protected List getDeclaredParameters() { 287 return declaredParameters; 288 } 289 290 291 294 public void afterPropertiesSet() { 295 compile(); 296 } 297 298 304 public final void compile() throws InvalidDataAccessApiUsageException { 305 if (!isCompiled()) { 306 if (getSql() == null) { 307 throw new InvalidDataAccessApiUsageException("sql is required"); 308 } 309 310 try { 311 this.jdbcTemplate.afterPropertiesSet(); 312 } 313 catch (IllegalArgumentException ex) { 314 throw new InvalidDataAccessApiUsageException(ex.getMessage()); 315 } 316 317 compileInternal(); 318 this.compiled = true; 319 320 if (logger.isDebugEnabled()) { 321 logger.debug("RdbmsOperation with SQL [" + getSql() + "] compiled"); 322 } 323 } 324 } 325 326 334 protected abstract void compileInternal() throws InvalidDataAccessApiUsageException; 335 336 342 public boolean isCompiled() { 343 return compiled; 344 } 345 346 352 protected void checkCompiled() { 353 if (!isCompiled()) { 354 logger.debug("SQL operation not compiled before execution - invoking compile"); 355 compile(); 356 } 357 } 358 359 366 protected void validateParameters(Object [] parameters) throws InvalidDataAccessApiUsageException { 367 checkCompiled(); 368 369 int declaredInParameters = 0; 370 if (this.declaredParameters != null) { 371 Iterator it = this.declaredParameters.iterator(); 372 while (it.hasNext()) { 373 Object param = it.next(); 374 if (!(param instanceof ResultSetSupportingSqlParameter)) { 375 if (!supportsLobParameters() && 376 (((SqlParameter) param).getSqlType() == Types.BLOB || 377 ((SqlParameter) param).getSqlType() == Types.CLOB)) { 378 throw new InvalidDataAccessApiUsageException( 379 "BLOB or CLOB parameters are not allowed for this kind of operation"); 380 } 381 declaredInParameters++; 382 } 383 } 384 } 385 386 if (parameters != null) { 387 if (this.declaredParameters == null) { 388 throw new InvalidDataAccessApiUsageException("Didn't expect any parameters: none was declared"); 389 } 390 if (parameters.length < declaredInParameters) { 391 throw new InvalidDataAccessApiUsageException( 392 parameters.length + " parameters were supplied, but " + 393 declaredInParameters + " in parameters were declared in class [" + 394 getClass().getName() + "]"); 395 } 396 if (!allowsUnusedParameters() && parameters.length > this.declaredParameters.size()) { 397 throw new InvalidDataAccessApiUsageException( 398 parameters.length + " parameters were supplied, but " + 399 this.declaredParameters.size() + " parameters were declared " + 400 "in class [" + getClass().getName() + "]"); 401 } 402 } 403 else { 404 if (this.declaredParameters != null && !this.declaredParameters.isEmpty()) { 406 throw new InvalidDataAccessApiUsageException( 407 this.declaredParameters.size() + " parameters must be supplied"); 408 } 409 } 410 } 411 412 419 protected void validateNamedParameters(Map parameters) throws InvalidDataAccessApiUsageException { 420 checkCompiled(); 421 422 if (this.declaredParameters != null) { 423 Iterator it = this.declaredParameters.iterator(); 424 while (it.hasNext()) { 425 Object param = it.next(); 426 if (!(param instanceof ResultSetSupportingSqlParameter)) { 427 if (!supportsLobParameters() && 428 (((SqlParameter) param).getSqlType() == Types.BLOB || 429 ((SqlParameter) param).getSqlType() == Types.CLOB)) { 430 throw new InvalidDataAccessApiUsageException( 431 "BLOB or CLOB parameters are not allowed for this kind of operation"); 432 } 433 if (((SqlParameter) param).getName() == null) { 434 throw new InvalidDataAccessApiUsageException( 435 "All parameters must have name specified when using the methods " + 436 "dedicated to named parameter support"); 437 } 438 if (!parameters.containsKey(((SqlParameter) param).getName())) { 439 throw new InvalidDataAccessApiUsageException( 440 "The parameter named '" + ((SqlParameter)param).getName() + 441 "' were not among the parameters supplied: " + 442 parameters.keySet()); 443 } 444 } 445 } 446 } 447 448 if (parameters != null && parameters.size() > 0) { 449 if (this.declaredParameters == null) { 450 throw new InvalidDataAccessApiUsageException("Didn't expect any parameters: none was declared"); 451 } 452 } 453 else { 454 if (this.declaredParameters != null && !this.declaredParameters.isEmpty()) { 456 throw new InvalidDataAccessApiUsageException("Parameters must be supplied"); 457 } 458 } 459 } 460 461 465 protected boolean supportsLobParameters() { 466 return true; 467 } 468 469 474 protected boolean allowsUnusedParameters() { 475 return false; 476 } 477 478 } 479 | Popular Tags |