All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.soulwing.jdbc.FluentJdbc Maven / Gradle / Ivy

/*
 * File created on May 5, 2014 
 *
 * Copyright (c) 2014 Carl Harris, Jr
 * and others as noted
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.soulwing.jdbc;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.soulwing.jdbc.logger.JdbcLogger;
import org.soulwing.jdbc.logger.NullJdbcLogger;
import org.soulwing.jdbc.logger.PrintWriterJdbcLogger;
import org.soulwing.jdbc.source.SQLSource;

/**
 * A thread-safe {@link JdbcOperations} implementation.
 * 

* This class must be constructed with a {@link DataSource} that will be used * as necessary to obtain connections to the database. *

 * import javax.sql.DataSource;
 * import org.soulwing.jdbc.FluentJdbc;
 *
 * DataSource dataSource = ...  // typically injected or retrieved via JNDI
 * FluentJdbc sqlTemplate = new FluentJdbc(dataSource);
 * 
* * A single instance of this class that is constructed with an appropriate * {@link DataSource} can be concurrently shared by an arbitrary number of * application components. * * @author Carl Harris */ public class FluentJdbc implements JdbcOperations { private final DataSource dataSource; private JdbcLogger logger = NullJdbcLogger.INSTANCE; private boolean autoCommit; private boolean ignoreErrors; /** * Constructs a new instance. * @param dataSource data source that will be used to obtain connections to * the database */ public FluentJdbc(DataSource dataSource) { this.dataSource = dataSource; } /** * Constructs a new instance for use by a single thread. *

* Use this constructor to create a facade instance that uses the given * connection whenever a connection to the database is needed. This allows * the facade to be used in conjunction with a framework such as * Flyway that wants to explicit manage * transaction state by providing a specific connection to each operation * that needs one. *

* Because an instance created via this constructor uses a single database * connection, it should not be used by multiple concurrent threads. * * @param connection connection that will be used for all JDBC operations * invoked using this facade instance */ public FluentJdbc(Connection connection) { this(new SingleConnectionDataSource(connection)); } /** * {@inheritDoc} */ @Override public void execute(String sql) { doExecute(sql, dataSource); } /** * {@inheritDoc} */ @Override public void execute(SQLSource source) { execute(SourceUtils.getSingleStatement(source)); } /** * {@inheritDoc} */ @Override public void executeScript(SQLSource source) { Connection connection = null; Boolean autoCommit = null; try { connection = dataSource.getConnection(); if (this.autoCommit) { autoCommit = connection.getAutoCommit(); connection.setAutoCommit(true); } final SingleConnectionDataSource dataSource = new SingleConnectionDataSource(connection); String sql = source.next(); while (sql != null) { try { doExecute(sql, dataSource); } catch (SQLRuntimeException ex) { if (!ignoreErrors) { throw ex; } } sql = source.next(); } } catch (SQLException ex) { throw new SQLRuntimeException(ex); } finally { JdbcUtils.closeQuietly(source); if (autoCommit != null) { try { connection.setAutoCommit(autoCommit); } catch (SQLException ex) { throw new SQLRuntimeException(ex); } } if (connection != null) { JdbcUtils.closeQuietly(connection); } } } private void doExecute(String sql, DataSource dataSource) { final PreparedStatementCreator psc = StatementPreparer.with(sql); final StatementExecutor executor = new StatementExecutor(psc, logger); try { executor.execute(dataSource); } catch (SQLException ex) { throw new SQLRuntimeException(ex); } finally { JdbcUtils.closeQuietly(psc); } } /** * {@inheritDoc} */ @Override public JdbcQuery query() { return queryForType(Void.class); } /** * {@inheritDoc} */ @Override public JdbcQuery queryForType(Class type) { return new QueryBuilder<>(type, dataSource, logger); } /** * {@inheritDoc} */ @Override public JdbcUpdate update() { return new UpdateBuilder(dataSource, logger); } /** * {@inheritDoc} */ @Override public JdbcCall call(String sql) { return new CallBuilder(dataSource, CallPreparer.with(sql), logger); } /** * {@inheritDoc} */ @Override public JdbcCall call(SQLSource source) { return new CallBuilder(dataSource, CallPreparer.with(source), logger); } /** * Sets the logger to use for SQL statement logging. * @param logger the logger to set (may be {@code null} to disable logging) */ public void setLogger(JdbcLogger logger) { if (logger == null) { logger = NullJdbcLogger.INSTANCE; } this.logger = logger; } /** * Sets a print writer to use for SQL statement logging. * @param writer the logger to set (may be {@code null} to disable logging) */ public void setLogger(PrintWriter writer) { setLogger(writer, false); } /** * Sets a print writer to use for SQL statement logging. * @param writer the logger to set (may be {@code null} to disable logging) * @param traceEnabled flag indicating whether trace level logging should * be used */ public void setLogger(PrintWriter writer, boolean traceEnabled) { setLogger(new PrintWriterJdbcLogger(writer, traceEnabled)); } /** * Sets a print stream to use for SQL statement logging. * @param stream the logger to set (may be {@code null} to disable logging) */ public void setLogger(PrintStream stream) { setLogger(stream, false); } /** * Sets a print stream to use for SQL statement logging. * @param stream the logger to set (may be {@code null} to disable logging) * @param traceEnabled flag indicating whether trace level logging should * be used * */ public void setLogger(PrintStream stream, boolean traceEnabled) { setLogger(new PrintWriterJdbcLogger(stream, traceEnabled)); } /** * Gets the {@code autoCommit} flag state. *

* @return {@code true} if {@link #executeScript(SQLSource) executeScript} * will use auto-commit mode */ public boolean isAutoCommit() { return autoCommit; } /** * Sets the {@code autoCommit} flag. *

* This state of this flag is checked when {@link #executeScript(SQLSource) * executeScript} is invoked. If {@code true}, all statements executed by * the script will be auto-committed. *

* In a managed transaction environment (e.g. in a Java EE application) * setting this flag to {@code true} may cause script execution to fail. * * @param autoCommit the auto-commit flag state to set */ public void setAutoCommit(boolean autoCommit) { this.autoCommit = autoCommit; } /** * Gets the {@code ignoreErrors} flag state. * @return {@code true} if {@link #executeScript(SQLSource) executeScript} * will ignore errors at the statement level */ public boolean isIgnoreErrors() { return ignoreErrors; } /** * Sets the {@code ignoreErrors} flag. *

* This state of this flag is checked when {@link #executeScript(SQLSource) * executeScript} is invoked. If {@code true}, errors thrown by the execution * of any given statement will be ignored. *

* In general, ignoring errors is effective only when the * {@linkplain #setAutoCommit(boolean) auto-commit} flag is also set to * {@code true}. * * @param ignoreErrors the flag state to set */ public void setIgnoreErrors(boolean ignoreErrors) { this.ignoreErrors = ignoreErrors; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy