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

org.sql2o.Sql2o Maven / Gradle / Ivy

There is a newer version: 0.2.6
Show newest version
package org.sql2o;

import org.sql2o.connectionsources.DataSourceConnectionSource;
import org.sql2o.connectionsources.ConnectionSource;
import org.sql2o.quirks.Quirks;
import org.sql2o.quirks.QuirksDetector;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Sql2o is the main class for the sql2o library.
 * 

* An Sql2o instance represents a way of connecting to one specific database. * To create a new instance, one need to specify either jdbc-url, username and password for the database or a data source. *

* Internally the Sql2o instance uses a data source to create jdbc connections to the database. If url, username and password * was specified in the constructor, a simple data source is created, which works as a simple wrapper around the jdbc * driver. *

* Some jdbc implementations have quirks, therefore it may be necessary to use a constructor with the quirks parameter. * When quirks are specified, Sql2o will use workarounds to avoid these quirks. * * @author Lars Aaberg */ public class Sql2o { private final Quirks quirks; private Map defaultColumnMappings; private boolean defaultCaseSensitive; private int isolationLevel; private ConnectionSource connectionSource; public Sql2o(String jndiLookup) { this(JndiDataSource.getJndiDatasource(jndiLookup)); } /** * Creates a new instance of the Sql2o class. Internally this constructor will create a {@link GenericDatasource}, * and call the {@link Sql2o#Sql2o(DataSource)} constructor which takes a DataSource as parameter. * * @param url JDBC database url * @param user database username * @param pass database password */ public Sql2o(String url, String user, String pass) { this(url, user, pass, QuirksDetector.forURL(url)); } /** * Created a new instance of the Sql2o class. Internally this constructor will create a {@link GenericDatasource}, * and call the {@link Sql2o#Sql2o(DataSource)} constructor which takes a DataSource as parameter. * * @param url JDBC database url * @param user database username * @param pass database password * @param quirks {@link Quirks} allows sql2o to work around known quirks and issues in different JDBC drivers. */ public Sql2o(String url, String user, String pass, Quirks quirks) { this(new GenericDatasource(url, user, pass), quirks); } /** * Creates a new instance of the Sql2o class, which uses the given DataSource to acquire connections to the database. * * @param dataSource The DataSource Sql2o uses to acquire connections to the database. */ public Sql2o(DataSource dataSource) { this(dataSource, QuirksDetector.forObject(dataSource)); } /** * Creates a new instance of the Sql2o class, which uses the given DataSource to acquire connections to the database. * * @param dataSource The DataSource Sql2o uses to acquire connections to the database. * @param quirks {@link Quirks} allows sql2o to work around known quirks and issues in different JDBC drivers. */ public Sql2o(DataSource dataSource, Quirks quirks) { this.connectionSource = new DataSourceConnectionSource(dataSource); this.quirks = quirks; this.defaultColumnMappings = new HashMap<>(); } public Quirks getQuirks() { return quirks; } /** * Gets the {@link ConnectionSource} that Sql2o uses internally to acquire database connections. * * @return The ConnectionSource instance */ public ConnectionSource getConnectionSource() { return connectionSource; } /** * Sets the {@link ConnectionSource} that Sql2o uses internally to acquire database connections. * * @param connectionSource the ConnectionSource instance to use */ public void setConnectionSource(ConnectionSource connectionSource) { this.connectionSource = connectionSource; } /** * Gets the default column mappings Map. column mappings added to this Map are always available when Sql2o attempts * to map between result sets and object instances. * * @return The {@link Map} instance, which Sql2o internally uses to map column names with property * names. */ public Map getDefaultColumnMappings() { return defaultColumnMappings; } /** * Sets the default column mappings Map. * * @param defaultColumnMappings A {@link Map} instance Sql2o uses internally to map between column names and * property names. */ public void setDefaultColumnMappings(Map defaultColumnMappings) { this.defaultColumnMappings = defaultColumnMappings; } /** * Gets value indicating if this instance of Sql2o is case sensitive when mapping between columns names and property * names. * * @return */ public boolean isDefaultCaseSensitive() { return defaultCaseSensitive; } /** * Sets a value indicating if this instance of Sql2o is case sensitive when mapping between columns names and property * names. This should almost always be false, because most relational databases are not case sensitive. * * @param defaultCaseSensitive */ public void setDefaultCaseSensitive(boolean defaultCaseSensitive) { this.defaultCaseSensitive = defaultCaseSensitive; } public void setIsolationLevel(int isolationLevel) { this.isolationLevel = isolationLevel; } /** * Opens a connection to the database * * @param connectionSource the {@link ConnectionSource} implementation substitution, * that will be used instead of one from {@link Sql2o} instance. * @return instance of the {@link Connection} class. */ public Connection open(ConnectionSource connectionSource) { return new Connection(this, connectionSource, false); } /** * Opens a connection to the database * * @return instance of the {@link Connection} class. */ public Connection open() { return new Connection(this, false); } /** * Invokes the run method on the {@link StatementRunnableWithResult} instance. This method guarantees that * the connection is closed properly, when either the run method completes or if an exception occurs. * * @param runnable * @param argument * @param * @return */ public V withConnection(StatementRunnableWithResult runnable, Object argument) { Connection connection = null; try { connection = open(); return (V) runnable.run(connection, argument); } catch (Throwable t) { throw new Sql2oException("An error occurred while executing StatementRunnable", t); } finally { if (connection != null) { connection.close(); } } } /** * Invokes the run method on the {@link StatementRunnableWithResult} instance. This method guarantees that * the connection is closed properly, when either the run method completes or if an exception occurs. * * @param runnable * @param * @return */ public V withConnection(StatementRunnableWithResult runnable) { return withConnection(runnable, null); } /** * Invokes the run method on the {@link StatementRunnableWithResult} instance. This method guarantees that * the connection is closed properly, when either the run method completes or if an exception occurs. * * @param runnable */ public void withConnection(StatementRunnable runnable) { withConnection(runnable, null); } /** * Invokes the run method on the {@link StatementRunnableWithResult} instance. This method guarantees that * the connection is closed properly, when either the run method completes or if an exception occurs. * * @param runnable * @param argument */ public void withConnection(StatementRunnable runnable, Object argument) { Connection connection = null; try { connection = open(); runnable.run(connection, argument); } catch (Throwable t) { throw new Sql2oException("An error occurred while executing StatementRunnable", t); } finally { if (connection != null) { connection.close(); } } } /** * Begins a transaction with the given isolation level. Every statement executed on the return {@link Connection} * instance, will be executed in the transaction. It is very important to always call either the {@link Connection#commit()} * method or the {@link Connection#rollback()} method to close the transaction. Use proper try-catch logic. * * @param isolationLevel the isolation level of the transaction * @return the {@link Connection} instance to use to run statements in the transaction. */ public Connection beginTransaction(int isolationLevel) { return beginTransaction(getConnectionSource(), isolationLevel); } /** * Begins a transaction with the given isolation level. Every statement executed on the return {@link Connection} * instance, will be executed in the transaction. It is very important to always call either the {@link Connection#commit()} * method or the {@link Connection#rollback()} method to close the transaction. Use proper try-catch logic. * * @param connectionSource the {@link ConnectionSource} implementation substitution, * that will be used instead of one from {@link Sql2o} instance. * @param isolationLevel the isolation level of the transaction * @return the {@link Connection} instance to use to run statements in the transaction. */ public Connection beginTransaction(ConnectionSource connectionSource, int isolationLevel) { Connection connection = new Connection(this, connectionSource, false); boolean success = false; try { connection.getJdbcConnection().setAutoCommit(false); connection.getJdbcConnection().setTransactionIsolation(isolationLevel); success = true; } catch (SQLException e) { throw new Sql2oException("Could not start the transaction - " + e.getMessage(), e); } finally { if (!success) { connection.close(); } } return connection; } /** * Begins a transaction with isolation level {@link java.sql.Connection#TRANSACTION_READ_COMMITTED}. Every statement executed on the return {@link Connection} * instance, will be executed in the transaction. It is very important to always call either the {@link Connection#commit()} * method or the {@link Connection#rollback()} method to close the transaction. Use proper try-catch logic. * * @return the {@link Connection} instance to use to run statements in the transaction. */ public Connection beginTransaction() { if (isolationLevel > 0) { return this.beginTransaction(this.isolationLevel); } return this.beginTransaction(java.sql.Connection.TRANSACTION_READ_COMMITTED); } /** * Begins a transaction with isolation level {@link java.sql.Connection#TRANSACTION_READ_COMMITTED}. Every statement executed on the return {@link Connection} * instance, will be executed in the transaction. It is very important to always call either the {@link Connection#commit()} * method or the {@link Connection#rollback()} method to close the transaction. Use proper try-catch logic. * * @param connectionSource the {@link ConnectionSource} implementation substitution, * that will be used instead of one from {@link Sql2o} instance. * @return the {@link Connection} instance to use to run statements in the transaction. */ public Connection beginTransaction(ConnectionSource connectionSource) { return this.beginTransaction(connectionSource, java.sql.Connection.TRANSACTION_READ_COMMITTED); } /** * Calls the {@link StatementRunnable#run(Connection, Object)} method on the {@link StatementRunnable} parameter. All statements * run on the {@link Connection} instance in the {@link StatementRunnable#run(Connection, Object) run} method will be * executed in a transaction. The transaction will automatically be committed if the {@link StatementRunnable#run(Connection, Object) run} * method finishes without throwing an exception. If an exception is thrown within the {@link StatementRunnable#run(Connection, Object) run} method, * the transaction will automatically be rolled back. *

* The isolation level of the transaction will be set to {@link java.sql.Connection#TRANSACTION_READ_COMMITTED} * * @param runnable The {@link StatementRunnable} instance. */ public void runInTransaction(StatementRunnable runnable) { runInTransaction(runnable, null); } /** * Calls the {@link StatementRunnable#run(Connection, Object)} method on the {@link StatementRunnable} parameter. All statements * run on the {@link Connection} instance in the {@link StatementRunnable#run(Connection, Object) run} method will be * executed in a transaction. The transaction will automatically be committed if the {@link StatementRunnable#run(Connection, Object) run} * method finishes without throwing an exception. If an exception is thrown within the {@link StatementRunnable#run(Connection, Object) run} method, * the transaction will automatically be rolled back. *

* The isolation level of the transaction will be set to {@link java.sql.Connection#TRANSACTION_READ_COMMITTED} * * @param runnable The {@link StatementRunnable} instance. * @param argument An argument which will be forwarded to the {@link StatementRunnable#run(Connection, Object) run} method */ public void runInTransaction(StatementRunnable runnable, Object argument) { runInTransaction(runnable, argument, java.sql.Connection.TRANSACTION_READ_COMMITTED); } /** * Calls the {@link StatementRunnable#run(Connection, Object)} method on the {@link StatementRunnable} parameter. All statements * run on the {@link Connection} instance in the {@link StatementRunnable#run(Connection, Object) run} method will be * executed in a transaction. The transaction will automatically be committed if the {@link StatementRunnable#run(Connection, Object) run} * method finishes without throwing an exception. If an exception is thrown within the {@link StatementRunnable#run(Connection, Object) run} method, * the transaction will automatically be rolled back. * * @param runnable The {@link StatementRunnable} instance. * @param argument An argument which will be forwarded to the {@link StatementRunnable#run(Connection, Object) run} method * @param isolationLevel The isolation level of the transaction */ public void runInTransaction(StatementRunnable runnable, Object argument, int isolationLevel) { Connection connection = this.beginTransaction(isolationLevel); connection.setRollbackOnException(false); try { runnable.run(connection, argument); } catch (Throwable throwable) { connection.rollback(); throw new Sql2oException("An error occurred while executing StatementRunnable. Transaction is rolled back.", throwable); } connection.commit(); } public V runInTransaction(StatementRunnableWithResult runnableWithResult) { return runInTransaction(runnableWithResult, null); } public V runInTransaction(StatementRunnableWithResult runnableWithResult, Object argument) { return runInTransaction(runnableWithResult, argument, java.sql.Connection.TRANSACTION_READ_COMMITTED); } @SuppressWarnings("unchecked") public V runInTransaction(StatementRunnableWithResult runnableWithResult, Object argument, int isolationLevel) { Connection connection = this.beginTransaction(isolationLevel); Object result; try { result = runnableWithResult.run(connection, argument); } catch (Throwable throwable) { connection.rollback(); throw new Sql2oException("An error occurred while executing StatementRunnableWithResult. Transaction rolled back.", throwable); } connection.commit(); return (V) result; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy