1 16 package com.ibatis.sqlmap.engine.execution; 17 18 import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMapping; 19 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap; 20 import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping; 21 import com.ibatis.sqlmap.engine.mapping.result.ResultMap; 22 import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback; 23 import com.ibatis.sqlmap.engine.scope.ErrorContext; 24 import com.ibatis.sqlmap.engine.scope.RequestScope; 25 import com.ibatis.sqlmap.engine.scope.SessionScope; 26 27 import java.sql.*; 28 import java.util.ArrayList ; 29 import java.util.List ; 30 31 34 public class SqlExecutor { 35 36 40 43 public static final int NO_SKIPPED_RESULTS = 0; 44 45 48 public static final int NO_MAXIMUM_RESULTS = -999999; 49 50 54 66 public int executeUpdate(RequestScope request, Connection conn, String sql, Object [] parameters) 67 throws SQLException { 68 ErrorContext errorContext = request.getErrorContext(); 69 errorContext.setActivity("executing update"); 70 errorContext.setObjectId(sql); 71 72 PreparedStatement ps = null; 73 int rows = 0; 74 75 try { 76 errorContext.setMoreInfo("Check the SQL Statement (preparation failed)."); 77 ps = conn.prepareStatement(sql); 78 79 errorContext.setMoreInfo("Check the parameters (set parameters failed)."); 80 request.getParameterMap().setParameters(request, ps, parameters); 81 82 errorContext.setMoreInfo("Check the statement (update failed)."); 83 84 ps.execute(); 85 rows = ps.getUpdateCount(); 86 } 87 finally { 88 closeStatement(ps); 89 } 90 91 return rows; 92 } 93 94 104 public void addBatch(RequestScope request, Connection conn, String sql, Object [] parameters) 105 throws SQLException { 106 Batch batch = (Batch) request.getSession().getBatch(); 107 if (batch == null) { 108 batch = new Batch(); 109 request.getSession().setBatch(batch); 110 } 111 batch.addBatch(request, conn, sql, parameters); 112 } 113 114 123 public int executeBatch(SessionScope session) 124 throws SQLException { 125 int rows = 0; 126 Batch batch = (Batch) session.getBatch(); 127 if (batch != null) { 128 try { 129 rows = batch.executeBatch(); 130 } finally { 131 batch.cleanupBatch(); 132 } 133 } 134 return rows; 135 } 136 137 150 public void executeQuery(RequestScope request, Connection conn, String sql, Object [] parameters, 151 int skipResults, int maxResults, RowHandlerCallback callback) 152 throws SQLException { 153 ErrorContext errorContext = request.getErrorContext(); 154 errorContext.setActivity("executing query"); 155 errorContext.setObjectId(sql); 156 157 PreparedStatement ps = null; 158 ResultSet rs = null; 159 160 try { 161 errorContext.setMoreInfo("Check the SQL Statement (preparation failed)."); 162 163 Integer rsType = request.getStatement().getResultSetType(); 164 if (rsType != null) { 165 ps = conn.prepareStatement(sql, rsType.intValue(), ResultSet.CONCUR_READ_ONLY); 166 } else { 167 ps = conn.prepareStatement(sql); 168 } 169 170 Integer fetchSize = request.getStatement().getFetchSize(); 171 if (fetchSize != null) { 172 ps.setFetchSize(fetchSize.intValue()); 173 } 174 175 errorContext.setMoreInfo("Check the parameters (set parameters failed)."); 176 request.getParameterMap().setParameters(request, ps, parameters); 177 178 errorContext.setMoreInfo("Check the statement (query failed)."); 179 180 ps.execute(); 181 rs = ps.getResultSet(); 182 183 errorContext.setMoreInfo("Check the results (failed to retrieve results)."); 184 handleResults(request, rs, skipResults, maxResults, callback); 185 186 while (ps.getMoreResults()); 188 189 } finally { 190 try { 191 closeResultSet(rs); 192 } finally { 193 closeStatement(ps); 194 } 195 } 196 197 } 198 199 211 public int executeUpdateProcedure(RequestScope request, Connection conn, String sql, Object [] parameters) 212 throws SQLException { 213 ErrorContext errorContext = request.getErrorContext(); 214 errorContext.setActivity("executing update procedure"); 215 errorContext.setObjectId(sql); 216 217 CallableStatement cs = null; 218 int rows = 0; 219 220 try { 221 errorContext.setMoreInfo("Check the SQL Statement (preparation failed)."); 222 cs = conn.prepareCall(sql); 223 224 ParameterMap parameterMap = request.getParameterMap(); 225 226 ParameterMapping[] mappings = parameterMap.getParameterMappings(); 227 228 errorContext.setMoreInfo("Check the output parameters (register output parameters failed)."); 229 registerOutputParameters(cs, mappings); 230 231 errorContext.setMoreInfo("Check the parameters (set parameters failed)."); 232 parameterMap.setParameters(request, cs, parameters); 233 234 errorContext.setMoreInfo("Check the statement (update procedure failed)."); 235 236 cs.execute(); 237 rows = cs.getUpdateCount(); 238 239 errorContext.setMoreInfo("Check the output parameters (retrieval of output parameters failed)."); 240 retrieveOutputParameters(cs, mappings, parameters); 241 } finally { 242 closeStatement(cs); 243 } 244 245 return rows; 246 } 247 248 261 public void executeQueryProcedure(RequestScope request, Connection conn, String sql, Object [] parameters, 262 int skipResults, int maxResults, RowHandlerCallback callback) 263 throws SQLException { 264 ErrorContext errorContext = request.getErrorContext(); 265 errorContext.setActivity("executing query procedure"); 266 errorContext.setObjectId(sql); 267 268 CallableStatement cs = null; 269 ResultSet rs = null; 270 271 try { 272 errorContext.setMoreInfo("Check the SQL Statement (preparation failed)."); 273 cs = conn.prepareCall(sql); 274 275 ParameterMap parameterMap = request.getParameterMap(); 276 277 ParameterMapping[] mappings = parameterMap.getParameterMappings(); 278 279 errorContext.setMoreInfo("Check the output parameters (register output parameters failed)."); 280 registerOutputParameters(cs, mappings); 281 282 errorContext.setMoreInfo("Check the parameters (set parameters failed)."); 283 parameterMap.setParameters(request, cs, parameters); 284 285 errorContext.setMoreInfo("Check the statement (update procedure failed)."); 286 287 cs.execute(); 288 rs = cs.getResultSet(); 289 290 errorContext.setMoreInfo("Check the results (failed to retrieve results)."); 291 handleResults(request, rs, skipResults, maxResults, callback); 292 293 while (cs.getMoreResults()); 295 296 errorContext.setMoreInfo("Check the output parameters (retrieval of output parameters failed)."); 297 retrieveOutputParameters(cs, mappings, parameters); 298 299 } finally { 300 try { 301 closeResultSet(rs); 302 } finally { 303 closeStatement(cs); 304 } 305 } 306 307 } 308 309 314 public void cleanup(SessionScope session) { 315 Batch batch = (Batch) session.getBatch(); 316 if (batch != null) { 317 batch.cleanupBatch(); 318 session.setBatch(null); 319 } 320 } 321 322 326 private void retrieveOutputParameters(CallableStatement cs, ParameterMapping[] mappings, Object [] parameters) throws SQLException { 327 for (int i = 0; i < mappings.length; i++) { 328 BasicParameterMapping mapping = ((BasicParameterMapping) mappings[i]); 329 if (mapping.isOutputAllowed()) { 330 Object o = mapping.getTypeHandler().getResult(cs, i + 1); 331 parameters[i] = o; 332 } 333 } 334 } 335 336 private void registerOutputParameters(CallableStatement cs, ParameterMapping[] mappings) throws SQLException { 337 for (int i = 0; i < mappings.length; i++) { 338 BasicParameterMapping mapping = ((BasicParameterMapping) mappings[i]); 339 if (mapping.isOutputAllowed()) { 340 if ( null != mapping.getTypeName() && !mapping.getTypeName().equals("") ) { cs.registerOutParameter(i + 1, mapping.getJdbcType(), mapping.getTypeName() ); 342 } else { 343 cs.registerOutParameter(i + 1, mapping.getJdbcType()); 344 } 345 } 346 } 347 } 348 349 private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException { 350 try { 351 request.setResultSet(rs); 352 ResultMap resultMap = request.getResultMap(); 353 if (resultMap != null) { 354 if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) { 356 if (skipResults > 0) { 357 rs.absolute(skipResults); 358 } 359 } else { 360 for (int i = 0; i < skipResults; i++) { 361 if (!rs.next()) { 362 break; 363 } 364 } 365 } 366 367 int resultsFetched = 0; 369 while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults) && rs.next()) { 370 Object [] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs); 371 callback.handleResultObject(request, columnValues, rs); 372 resultsFetched++; 373 } 374 } 375 } finally { 376 request.setResultSet(null); 377 } 378 } 379 380 383 private static void closeStatement(PreparedStatement ps) { 384 if (ps != null) { 385 try { 386 ps.close(); 387 } catch (SQLException e) { 388 } 390 } 391 } 392 393 396 private static void closeResultSet(ResultSet rs) { 397 if (rs != null) { 398 try { 399 rs.close(); 400 } catch (SQLException e) { 401 } 403 } 404 } 405 406 410 private static class Batch { 411 private String currentSql; 412 private List statementList = new ArrayList (); 413 private int size; 414 private static final int SUCCESS_NO_INFO = -2; 415 private static final int EXECUTE_FAILED = -3; 416 417 420 public Batch() { 421 this.size = 0; 422 } 423 424 429 public int getSize() { 430 return size; 431 } 432 433 443 public void addBatch(RequestScope request, Connection conn, String sql, Object [] parameters) throws SQLException { 444 PreparedStatement ps = null; 445 if (currentSql != null 446 && sql.hashCode() == currentSql.hashCode() 447 && sql.length() == currentSql.length()) { 448 int last = statementList.size() - 1; 449 ps = (PreparedStatement) statementList.get(last); 450 } else { 451 ps = conn.prepareStatement(sql); 452 currentSql = sql; 453 statementList.add(ps); 454 } 455 request.getParameterMap().setParameters(request, ps, parameters); 456 ps.addBatch(); 457 size++; 458 } 459 460 467 public int executeBatch() throws SQLException { 468 int totalRowCount = 0; 469 for (int i = 0, n = statementList.size(); i < n; i++) { 470 PreparedStatement ps = (PreparedStatement) statementList.get(i); 471 int[] rowCounts = ps.executeBatch(); 472 for (int j = 0; j < rowCounts.length; j++) { 473 if (rowCounts[j] == SUCCESS_NO_INFO) { 474 } else if (rowCounts[j] == EXECUTE_FAILED) { 476 throw new SQLException("The batched statement at index " + j + " failed to execute."); 477 } else { 478 totalRowCount += rowCounts[j]; 479 } 480 } 481 } 482 return totalRowCount; 483 } 484 485 488 public void cleanupBatch() { 489 for (int i = 0, n = statementList.size(); i < n; i++) { 490 PreparedStatement ps = (PreparedStatement) statementList.get(i); 491 closeStatement(ps); 492 } 493 currentSql = null; 494 statementList.clear(); 495 size = 0; 496 } 497 } 498 499 } 500 | Popular Tags |