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