001/*
002 * Copyright 2002-2013 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.core.support;
018
019import java.sql.PreparedStatement;
020import java.sql.SQLException;
021
022import org.springframework.dao.DataAccessException;
023import org.springframework.jdbc.core.PreparedStatementCallback;
024import org.springframework.jdbc.support.lob.LobCreator;
025import org.springframework.jdbc.support.lob.LobHandler;
026import org.springframework.util.Assert;
027
028/**
029 * Abstract {@link PreparedStatementCallback} implementation that manages a {@link LobCreator}.
030 * Typically used as inner class, with access to surrounding method arguments.
031 *
032 * <p>Delegates to the {@code setValues} template method for setting values
033 * on the PreparedStatement, using a given LobCreator for BLOB/CLOB arguments.
034 *
035 * <p>A usage example with {@link org.springframework.jdbc.core.JdbcTemplate}:
036 *
037 * <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
038 * LobHandler lobHandler = new DefaultLobHandler();  // reusable object
039 *
040 * jdbcTemplate.execute(
041 *     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
042 *     new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
043 *       protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
044 *         ps.setString(1, name);
045 *         lobCreator.setBlobAsBinaryStream(ps, 2, contentStream, contentLength);
046 *         lobCreator.setClobAsString(ps, 3, description);
047 *       }
048 *     }
049 * );</pre>
050 *
051 * @author Juergen Hoeller
052 * @since 1.0.2
053 * @see org.springframework.jdbc.support.lob.LobCreator
054 */
055public abstract class AbstractLobCreatingPreparedStatementCallback implements PreparedStatementCallback<Integer> {
056
057        private final LobHandler lobHandler;
058
059
060        /**
061         * Create a new AbstractLobCreatingPreparedStatementCallback for the
062         * given LobHandler.
063         * @param lobHandler the LobHandler to create LobCreators with
064         */
065        public AbstractLobCreatingPreparedStatementCallback(LobHandler lobHandler) {
066                Assert.notNull(lobHandler, "LobHandler must not be null");
067                this.lobHandler = lobHandler;
068        }
069
070
071        @Override
072        public final Integer doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
073                LobCreator lobCreator = this.lobHandler.getLobCreator();
074                try {
075                        setValues(ps, lobCreator);
076                        return ps.executeUpdate();
077                }
078                finally {
079                        lobCreator.close();
080                }
081        }
082
083        /**
084         * Set values on the given PreparedStatement, using the given
085         * LobCreator for BLOB/CLOB arguments.
086         * @param ps the PreparedStatement to use
087         * @param lobCreator the LobCreator to use
088         * @throws SQLException if thrown by JDBC methods
089         * @throws DataAccessException in case of custom exceptions
090         */
091        protected abstract void setValues(PreparedStatement ps, LobCreator lobCreator)
092                        throws SQLException, DataAccessException;
093
094}