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

com.drunkendev.jdbc.JdbcHolder Maven / Gradle / Ivy

/*
 * JdbcHolder.java    Aug 24 2012, 22:10
 *
 * Copyright 2012 Drunken Dev.
 *
 * 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 com.drunkendev.jdbc;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;


/**
 * Pairs a {@link JdbcTemplate} and {@link TransactionTemplate} for a given JDBC
 * {@link DataSource}.
 *
 * @author  Brett Ryan
 * @since   1.0
 * @see     JdbcManager
 */
public class JdbcHolder {

    private final JdbcTemplate jdbcTemplate;
    private final DataSourceTransactionManager transactionManager;
    private TransactionTemplate defaultTransactionTemplate;
    private TransactionTemplate readOnlyTransactionTemplate;

    /**
     * Creates a new {@code JdbcHolder} instance for a {@link DataSource}.
     *
     * @param   dataSource
     *          Data source to create a holder for.
     */
    public JdbcHolder(DataSource dataSource) {
        this(new JdbcTemplate(dataSource));
    }

    /**
     * Creates a new {@code JdbcHolder} instance for a {@link JdbcTemplate}.
     *
     * @param   jdbcTemplate
     *          JDBC Template to create a holder for.
     */
    public JdbcHolder(JdbcTemplate jdbcTemplate) {
        DefaultTransactionDefinition readOnlyDef;

        readOnlyDef = new DefaultTransactionDefinition();
        readOnlyDef.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        readOnlyDef.setReadOnly(true);

        this.transactionManager = new DataSourceTransactionManager(jdbcTemplate.getDataSource());
        this.jdbcTemplate = jdbcTemplate;
        this.defaultTransactionTemplate = new TransactionTemplate(transactionManager);
        this.readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, readOnlyDef);
    }

    /**
     * Set the default transaction definition for default executions.
     *
     * This will replace the existing default template with a new one.
     *
     * @param   def
     *          New definition.
     */
    public void setTransactionDefinition(TransactionDefinition def) {
        this.defaultTransactionTemplate = new TransactionTemplate(transactionManager, def);
    }

    /**
     * Set the default transaction definition for read-only executions.
     *
     * This will replace the existing read-only template with a new one.
     *
     * @param   def
     *          New definition.
     */
    public void setReadOnlyTransactionDefinition(TransactionDefinition def) {
        this.readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, def);
    }

    /**
     * Gets the JDBC Template definition for this connection.
     *
     * @return  JDBC Template for this holder.
     */
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    /**
     * Retrieve the {@link DataSourceTransactionManager} for this holder.
     *
     * @return  Transaction manager for this holder.
     */
    public DataSourceTransactionManager getDataSourceTransactionManager() {
        return transactionManager;
    }

    /**
     * Execute a callback to return a result.
     *
     * The callback function will be passed a {@link JdbcTemplate} instance for
     * JDBC execution and a {@link TransactionStatus} for transactional support.
     *
     * Note that this method will create a new {@link TransactionDefinition}
     * instance to execute the query with.
     *
     * 

Example

* *
     * {@code
     *  DefaultTransactionDefinition def = new DefaultTransactionDefinition();
     *  def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
     *  List custs = holder.execute(def, (template, status)
     *        -> template.query("select * from customer", MAPPER_CUSTOMER));
     * }
     * 
* * @param * Return type * @param def * Definition to * @param callback * Function used to perform the data access operation. * @return Result of the {@code callback} function. * @throws DataAccessException * if an underlying data access error occurs. * @see #execute(BiFunction) * @see #executeReadOnly(BiFunction) * @see #executeReadOnlyVoid(BiConsumer) * @see #executeVoid(BiConsumer) */ public T execute(TransactionDefinition def, BiFunction callback) throws DataAccessException { return new TransactionTemplate(transactionManager, def) .execute(ts -> callback.apply(jdbcTemplate, ts)); } /** * Execute a callback to return a result. * * The callback function will be passed a {@link JdbcTemplate} instance for * JDBC execution and a {@link TransactionStatus} for transactional support. * * Note that this method will create a new {@link TransactionDefinition} * instance to execute the query with. * *

Example

* *
     * {@code
     *  List custs = holder.execute((template, status)
     *        -> template.query("select * from customer", MAPPER_CUSTOMER));
     * }
     * 
* * @param * Return type * @param callback * Function used to perform the data access operation. * @return Result of the {@code callback} function. * @throws DataAccessException * if an underlying data access error occurs. * @see #execute(TransactionDefinition, BiFunction) * @see #executeReadOnly(BiFunction) * @see #executeReadOnlyVoid(BiConsumer) * @see #executeVoid(BiConsumer) */ public T execute(BiFunction callback) throws DataAccessException { return defaultTransactionTemplate.execute(ts -> callback.apply(jdbcTemplate, ts)); } /** * Execute a callback that does not return a result. * * The callback function will be passed a {@link JdbcTemplate} instance for * JDBC execution and a {@link TransactionStatus} for transactional support. * *

Example

* *
     * {@code
     *  holder.executeVoid((template, status)
     *        -> template.upate("insert into customer (id, name) values (?, ?)",
     *                          id, name));
     * }
     * 
* * @param callback * Function used to perform the data access operation. * @throws DataAccessException * if an underlying data access error occurs. * @see #execute(BiFunction) * @see #execute(TransactionDefinition, BiFunction) * @see #executeReadOnly(BiFunction) * @see #executeReadOnlyVoid(BiConsumer) */ public void executeVoid(BiConsumer callback) throws DataAccessException { defaultTransactionTemplate.execute(ts -> { callback.accept(jdbcTemplate, ts); return null; }); } /** * Execute a callback to return a result with read only transactions. * * The callback function will be passed a {@link JdbcTemplate} instance for * JDBC execution and a {@link TransactionStatus} for transactional support. * * NOTE: The read-only flag is a hint to the transaction subsystem and does not * ensure an underlying read-only connection. * *

Example

* *
     * {@code
     *  List custs = holder.executeReadOnly((template, status)
     *        -> template.query("select * from customer", MAPPER_CUSTOMER));
     * }
     * 
* * @param * Return type * @param callback * Function used to perform the data access operation. * @return Result of the {@code callback} function. * @throws DataAccessException * if an underlying data access error occurs. * @see #execute(BiFunction) * @see #execute(TransactionDefinition, BiFunction) * @see #executeReadOnlyVoid(BiConsumer) * @see #executeVoid(BiConsumer) */ public T executeReadOnly(BiFunction callback) throws DataAccessException { return readOnlyTransactionTemplate.execute(ts -> callback.apply(jdbcTemplate, ts)); } /** * Execute a callback that does not return a result with read only transactions. * * The callback function will be passed a {@link JdbcTemplate} instance for * JDBC execution and a {@link TransactionStatus} for transactional support. * * NOTE: The read-only flag is a hint to the transaction subsystem and does not * ensure an underlying read-only connection. * * @param callback * Function used to perform the data access operation. * @throws DataAccessException * if an underlying data access error occurs. * @see #execute(BiFunction) * @see #execute(TransactionDefinition, BiFunction) * @see #executeReadOnly(BiFunction) * @see #executeVoid(BiConsumer) */ public void executeReadOnlyVoid(BiConsumer callback) throws DataAccessException { readOnlyTransactionTemplate.execute(ts -> { callback.accept(jdbcTemplate, ts); return null; }); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy