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.support.lob;
018
019import java.io.Closeable;
020import java.io.InputStream;
021import java.io.Reader;
022import java.sql.PreparedStatement;
023import java.sql.SQLException;
024
025/**
026 * Interface that abstracts potentially database-specific creation of large binary
027 * fields and large text fields. Does not work with {@code java.sql.Blob}
028 * and {@code java.sql.Clob} instances in the API, as some JDBC drivers
029 * do not support these types as such.
030 *
031 * <p>The LOB creation part is where {@link LobHandler} implementations usually
032 * differ. Possible strategies include usage of
033 * {@code PreparedStatement.setBinaryStream/setCharacterStream} but also
034 * {@code PreparedStatement.setBlob/setClob} with either a stream argument
035 * (requires JDBC 4.0) or {@code java.sql.Blob/Clob} wrapper objects.
036 *
037 * <p>A LobCreator represents a session for creating BLOBs: It is <i>not</i>
038 * thread-safe and needs to be instantiated for each statement execution or for
039 * each transaction. Each LobCreator needs to be closed after completion.
040 *
041 * <p>For convenient working with a PreparedStatement and a LobCreator,
042 * consider using {@link org.springframework.jdbc.core.JdbcTemplate} with an
043 *{@link org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback}
044 * implementation. See the latter's javadoc for details.
045 *
046 * @author Juergen Hoeller
047 * @since 04.12.2003
048 * @see #close()
049 * @see LobHandler#getLobCreator()
050 * @see DefaultLobHandler.DefaultLobCreator
051 * @see OracleLobHandler.OracleLobCreator
052 * @see java.sql.PreparedStatement#setBlob
053 * @see java.sql.PreparedStatement#setClob
054 * @see java.sql.PreparedStatement#setBytes
055 * @see java.sql.PreparedStatement#setBinaryStream
056 * @see java.sql.PreparedStatement#setString
057 * @see java.sql.PreparedStatement#setAsciiStream
058 * @see java.sql.PreparedStatement#setCharacterStream
059 */
060public interface LobCreator extends Closeable {
061
062        /**
063         * Set the given content as bytes on the given statement, using the given
064         * parameter index. Might simply invoke {@code PreparedStatement.setBytes}
065         * or create a Blob instance for it, depending on the database and driver.
066         * @param ps the PreparedStatement to the set the content on
067         * @param paramIndex the parameter index to use
068         * @param content the content as byte array, or {@code null} for SQL NULL
069         * @throws SQLException if thrown by JDBC methods
070         * @see java.sql.PreparedStatement#setBytes
071         */
072        void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content)
073                        throws SQLException;
074
075        /**
076         * Set the given content as binary stream on the given statement, using the given
077         * parameter index. Might simply invoke {@code PreparedStatement.setBinaryStream}
078         * or create a Blob instance for it, depending on the database and driver.
079         * @param ps the PreparedStatement to the set the content on
080         * @param paramIndex the parameter index to use
081         * @param contentStream the content as binary stream, or {@code null} for SQL NULL
082         * @throws SQLException if thrown by JDBC methods
083         * @see java.sql.PreparedStatement#setBinaryStream
084         */
085        void setBlobAsBinaryStream(
086                        PreparedStatement ps, int paramIndex, InputStream contentStream, int contentLength)
087                        throws SQLException;
088
089        /**
090         * Set the given content as String on the given statement, using the given
091         * parameter index. Might simply invoke {@code PreparedStatement.setString}
092         * or create a Clob instance for it, depending on the database and driver.
093         * @param ps the PreparedStatement to the set the content on
094         * @param paramIndex the parameter index to use
095         * @param content the content as String, or {@code null} for SQL NULL
096         * @throws SQLException if thrown by JDBC methods
097         * @see java.sql.PreparedStatement#setBytes
098         */
099        void setClobAsString(PreparedStatement ps, int paramIndex, String content)
100                        throws SQLException;
101
102        /**
103         * Set the given content as ASCII stream on the given statement, using the given
104         * parameter index. Might simply invoke {@code PreparedStatement.setAsciiStream}
105         * or create a Clob instance for it, depending on the database and driver.
106         * @param ps the PreparedStatement to the set the content on
107         * @param paramIndex the parameter index to use
108         * @param asciiStream the content as ASCII stream, or {@code null} for SQL NULL
109         * @throws SQLException if thrown by JDBC methods
110         * @see java.sql.PreparedStatement#setAsciiStream
111         */
112        void setClobAsAsciiStream(
113                        PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength)
114                        throws SQLException;
115
116        /**
117         * Set the given content as character stream on the given statement, using the given
118         * parameter index. Might simply invoke {@code PreparedStatement.setCharacterStream}
119         * or create a Clob instance for it, depending on the database and driver.
120         * @param ps the PreparedStatement to the set the content on
121         * @param paramIndex the parameter index to use
122         * @param characterStream the content as character stream, or {@code null} for SQL NULL
123         * @throws SQLException if thrown by JDBC methods
124         * @see java.sql.PreparedStatement#setCharacterStream
125         */
126        void setClobAsCharacterStream(
127                        PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength)
128                        throws SQLException;
129
130        /**
131         * Close this LobCreator session and free its temporarily created BLOBs and CLOBs.
132         * Will not need to do anything if using PreparedStatement's standard methods,
133         * but might be necessary to free database resources if using proprietary means.
134         * <p><b>NOTE</b>: Needs to be invoked after the involved PreparedStatements have
135         * been executed or the affected O/R mapping sessions have been flushed.
136         * Otherwise, the database resources for the temporary BLOBs might stay allocated.
137         */
138        @Override
139        void close();
140
141}