001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jdbc.object; 018 019import org.springframework.jdbc.core.PreparedStatementCreator; 020import org.springframework.jdbc.core.PreparedStatementCreatorFactory; 021import org.springframework.jdbc.core.PreparedStatementSetter; 022import org.springframework.jdbc.core.namedparam.NamedParameterUtils; 023import org.springframework.jdbc.core.namedparam.ParsedSql; 024 025/** 026 * Operation object representing a SQL-based operation such as a query or update, 027 * as opposed to a stored procedure. 028 * 029 * <p>Configures a {@link org.springframework.jdbc.core.PreparedStatementCreatorFactory} 030 * based on the declared parameters. 031 * 032 * @author Rod Johnson 033 * @author Juergen Hoeller 034 */ 035public abstract class SqlOperation extends RdbmsOperation { 036 037 /** 038 * Object enabling us to create PreparedStatementCreators efficiently, 039 * based on this class's declared parameters. 040 */ 041 private PreparedStatementCreatorFactory preparedStatementFactory; 042 043 /** Parsed representation of the SQL statement */ 044 private ParsedSql cachedSql; 045 046 /** Monitor for locking the cached representation of the parsed SQL statement */ 047 private final Object parsedSqlMonitor = new Object(); 048 049 050 /** 051 * Overridden method to configure the PreparedStatementCreatorFactory 052 * based on our declared parameters. 053 */ 054 @Override 055 protected final void compileInternal() { 056 this.preparedStatementFactory = new PreparedStatementCreatorFactory(getSql(), getDeclaredParameters()); 057 this.preparedStatementFactory.setResultSetType(getResultSetType()); 058 this.preparedStatementFactory.setUpdatableResults(isUpdatableResults()); 059 this.preparedStatementFactory.setReturnGeneratedKeys(isReturnGeneratedKeys()); 060 if (getGeneratedKeysColumnNames() != null) { 061 this.preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames()); 062 } 063 this.preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); 064 065 onCompileInternal(); 066 } 067 068 /** 069 * Hook method that subclasses may override to post-process compilation. 070 * This implementation does nothing. 071 * @see #compileInternal 072 */ 073 protected void onCompileInternal() { 074 } 075 076 /** 077 * Obtain a parsed representation of this operation's SQL statement. 078 * <p>Typically used for named parameter parsing. 079 */ 080 protected ParsedSql getParsedSql() { 081 synchronized (this.parsedSqlMonitor) { 082 if (this.cachedSql == null) { 083 this.cachedSql = NamedParameterUtils.parseSqlStatement(getSql()); 084 } 085 return this.cachedSql; 086 } 087 } 088 089 090 /** 091 * Return a PreparedStatementSetter to perform an operation 092 * with the given parameters. 093 * @param params the parameter array (may be {@code null}) 094 */ 095 protected final PreparedStatementSetter newPreparedStatementSetter(Object[] params) { 096 return this.preparedStatementFactory.newPreparedStatementSetter(params); 097 } 098 099 /** 100 * Return a PreparedStatementCreator to perform an operation 101 * with the given parameters. 102 * @param params the parameter array (may be {@code null}) 103 */ 104 protected final PreparedStatementCreator newPreparedStatementCreator(Object[] params) { 105 return this.preparedStatementFactory.newPreparedStatementCreator(params); 106 } 107 108 /** 109 * Return a PreparedStatementCreator to perform an operation 110 * with the given parameters. 111 * @param sqlToUse the actual SQL statement to use (if different from 112 * the factory's, for example because of named parameter expanding) 113 * @param params the parameter array (may be {@code null}) 114 */ 115 protected final PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) { 116 return this.preparedStatementFactory.newPreparedStatementCreator(sqlToUse, params); 117 } 118 119}