Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.landawn.abacus.util.SQLExecutor Maven / Gradle / Ivy
/*
* Copyright (C) 2015 HaiYang Li
*
* 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.landawn.abacus.util;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
import com.landawn.abacus.DataSet;
import com.landawn.abacus.DataSourceManager;
import com.landawn.abacus.DataSourceSelector;
import com.landawn.abacus.DirtyMarker;
import com.landawn.abacus.EntityId;
import com.landawn.abacus.IsolationLevel;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.condition.Condition;
import com.landawn.abacus.condition.ConditionFactory.CF;
import com.landawn.abacus.core.DirtyMarkerUtil;
import com.landawn.abacus.core.Seid;
import com.landawn.abacus.dataSource.SQLDataSource;
import com.landawn.abacus.exception.DuplicatedResultException;
import com.landawn.abacus.exception.UncheckedSQLException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.parser.ParserUtil;
import com.landawn.abacus.parser.ParserUtil.EntityInfo;
import com.landawn.abacus.parser.ParserUtil.PropInfo;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.type.TypeFactory;
import com.landawn.abacus.util.Columns.ColumnOne;
import com.landawn.abacus.util.ExceptionalStream.StreamE;
import com.landawn.abacus.util.Fn.IntFunctions;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.JdbcUtil.BiParametersSetter;
import com.landawn.abacus.util.JdbcUtil.BiRowMapper;
import com.landawn.abacus.util.JdbcUtil.RowExtractor;
import com.landawn.abacus.util.JdbcUtil.RowFilter;
import com.landawn.abacus.util.SQLBuilder.NAC;
import com.landawn.abacus.util.SQLBuilder.NLC;
import com.landawn.abacus.util.SQLBuilder.NSC;
import com.landawn.abacus.util.SQLBuilder.PAC;
import com.landawn.abacus.util.SQLBuilder.PLC;
import com.landawn.abacus.util.SQLBuilder.PSC;
import com.landawn.abacus.util.SQLBuilder.SP;
import com.landawn.abacus.util.SQLTransaction.CreatedBy;
import com.landawn.abacus.util.StringUtil.Strings;
import com.landawn.abacus.util.Tuple.Tuple2;
import com.landawn.abacus.util.Tuple.Tuple3;
import com.landawn.abacus.util.u.Nullable;
import com.landawn.abacus.util.u.Optional;
import com.landawn.abacus.util.u.OptionalBoolean;
import com.landawn.abacus.util.u.OptionalByte;
import com.landawn.abacus.util.u.OptionalChar;
import com.landawn.abacus.util.u.OptionalDouble;
import com.landawn.abacus.util.u.OptionalFloat;
import com.landawn.abacus.util.u.OptionalInt;
import com.landawn.abacus.util.u.OptionalLong;
import com.landawn.abacus.util.u.OptionalShort;
import com.landawn.abacus.util.function.BiConsumer;
import com.landawn.abacus.util.function.BiFunction;
import com.landawn.abacus.util.function.BinaryOperator;
import com.landawn.abacus.util.function.Consumer;
import com.landawn.abacus.util.function.Function;
import com.landawn.abacus.util.function.Predicate;
import com.landawn.abacus.util.function.Supplier;
import com.landawn.abacus.util.stream.Collector;
import com.landawn.abacus.util.stream.ObjIteratorEx;
import com.landawn.abacus.util.stream.Stream;
import com.landawn.abacus.util.stream.Stream.StreamEx;
/**
* SQLExecutor is a simple sql/jdbc utility class. SQL is supported with different format:
*
*
*
* INSERT INTO account (first_name, last_name, gui, last_update_time, create_time) VALUES (?, ?, ?, ?, ?)
* INSERT INTO account (first_name, last_name, gui, last_update_time, create_time) VALUES (#{firstName}, #{lastName}, #{gui}, #{lastUpdateTime}, #{createTime})
* INSERT INTO account (first_name, last_name, gui, last_update_time, create_time) VALUES (:firstName, :lastName, :gui, :lastUpdateTime, :createTime)
*
* All these kinds of SQLs can be generated by SQLBuilder
conveniently. Parameters with format of Object[]/List parameters are supported for parameterized SQL({@code id = ?}).
* Parameters with format of Object[]/List/Map/Entity are supported for named parameterized SQL({@code id = :id}).
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
*
*
* Here is sample of CRUD(create/read/update/delete):
*
========================================================================
*
*
* static final DataSource dataSource = JdbcUtil.createDataSource(...);
* static final SQLExecutor sqlExecutor = new SQLExecutor(dataSource);
* ...
* Account account = createAccount();
*
* // create
* String sql_insert = NE.insert(GUI, FIRST_NAME, LAST_NAME, LAST_UPDATE_TIME, CREATE_TIME).into(Account.class).sql();
* N.println(sql_insert);
* sqlExecutor.insert(sql_insert, account);
*
* // read
* String sql_selectByGUI = NE.selectFrom(Account.class, N.asSet(DEVICES)).where(L.eq(GUI, L.QME)).sql();
* N.println(sql_selectByGUI);
* Account dbAccount = sqlExecutor.findFirst(Account.class, sql_selectByGUI, account);
* assertEquals(account.getFirstName(), dbAccount.getFirstName());
*
* // update
* String sql_updateByLastName = NE.update(Account.class).set(FIRST_NAME).where(L.eq(LAST_NAME, L.QME)).sql();
* N.println(sql_updateByLastName);
* dbAccount.setFirstName("newFirstName");
* sqlExecutor.update(sql_updateByLastName, dbAccount);
*
* // delete
* String sql_deleteByFirstName = NE.deleteFrom(Account.class).where(L.eq(FIRST_NAME, L.QME)).sql();
* N.println(sql_deleteByFirstName);
* sqlExecutor.update(sql_deleteByFirstName, dbAccount);
*
* dbAccount = sqlExecutor.findFirst(Account.class, sql_selectByGUI, account);
* assertNull(dbAccount);
*
*
* ========================================================================
*
*
* If {@code conn} argument is null or not specified, {@code SQLExecutor} is responsible to get the connection from the
* internal {@code DataSource}, start and commit/roll back transaction for batch operations if needed, and close the
* connection finally. otherwise it's user's responsibility to do such jobs if {@code conn} is specified and not null.
*
*
* Transaction can be started:
*
*
* final SQLTransaction tran = sqlExecutor.beginTransaction(IsolationLevel.READ_COMMITTED);
*
* try {
* // sqlExecutor.insert(...);
* // sqlExecutor.update(...);
* // sqlExecutor.query(...);
*
* tran.commit();
* } finally {
* // The connection will be automatically closed after the transaction is committed or rolled back.
* tran.rollbackIfNotCommitted();
* }
*
*
*
*
* Spring Transaction is also supported and Integrated.
* If a method of this class is called where a Spring transaction is started with the {@code DataSource} inside this {@code SQLExecutor}, without {@code Connection} parameter specified,
* the {@code Connection} started the Spring Transaction will be used. Otherwise a {@code Connection} directly from the inside {@code DataSource}(Connection pool) will be borrowed and used.
*
*
* SQLExecutor is tread-safe.
*
* @author Haiyang Li
* @see
JdbcUtil
* @see com.landawn.abacus.annotation.ReadOnly
* @see com.landawn.abacus.annotation.ReadOnlyId
* @see com.landawn.abacus.annotation.NonUpdatable
* @see com.landawn.abacus.annotation.Transient
* @see com.landawn.abacus.annotation.Table
* @see com.landawn.abacus.annotation.Column
* @see com.landawn.abacus.condition.ConditionFactory
* @see com.landawn.abacus.condition.ConditionFactory.CF
* @see
http://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html
* @see
http://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html
* @see
http://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html
* @see
http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html
* @since 0.8
*/
public class SQLExecutor {
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(SQLExecutor.class);
/** The Constant ID. */
static final String ID = "id";
/** The Constant QUERY_WITH_DATA_SOURCE. */
static final String QUERY_WITH_DATA_SOURCE = "queryWithDataSource";
/** The Constant EXISTS_RESULT_SET_EXTRACTOR. */
private static final ResultExtractor
EXISTS_RESULT_SET_EXTRACTOR = new ResultExtractor() {
@Override
public Boolean apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
return rs.next();
}
};
/** The Constant COUNT_RESULT_SET_EXTRACTOR. */
private static final ResultExtractor COUNT_RESULT_SET_EXTRACTOR = new ResultExtractor() {
@Override
public Integer apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
int cnt = 0;
while (rs.next()) {
cnt++;
}
return cnt;
}
};
/** The Constant SINGLE_BOOLEAN_EXTRACTOR. */
private static final ResultExtractor SINGLE_BOOLEAN_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalBoolean apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalBoolean.of(rs.getBoolean(1));
}
return OptionalBoolean.empty();
}
};
/** The Constant charType. */
private static final Type charType = TypeFactory.getType(char.class);
/** The Constant SINGLE_CHAR_EXTRACTOR. */
private static final ResultExtractor SINGLE_CHAR_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalChar apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalChar.of(charType.get(rs, 1));
}
return OptionalChar.empty();
}
};
/** The Constant SINGLE_BYTE_EXTRACTOR. */
private static final ResultExtractor SINGLE_BYTE_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalByte apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalByte.of(rs.getByte(1));
}
return OptionalByte.empty();
}
};
/** The Constant SINGLE_SHORT_EXTRACTOR. */
private static final ResultExtractor SINGLE_SHORT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalShort apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalShort.of(rs.getShort(1));
}
return OptionalShort.empty();
}
};
/** The Constant SINGLE_INT_EXTRACTOR. */
private static final ResultExtractor SINGLE_INT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalInt apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalInt.of(rs.getInt(1));
}
return OptionalInt.empty();
}
};
/** The Constant SINGLE_LONG_EXTRACTOR. */
private static final ResultExtractor SINGLE_LONG_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalLong apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalLong.of(rs.getLong(1));
}
return OptionalLong.empty();
}
};
/** The Constant SINGLE_FLOAT_EXTRACTOR. */
private static final ResultExtractor SINGLE_FLOAT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalFloat apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalFloat.of(rs.getFloat(1));
}
return OptionalFloat.empty();
}
};
/** The Constant SINGLE_DOUBLE_EXTRACTOR. */
private static final ResultExtractor SINGLE_DOUBLE_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalDouble apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return OptionalDouble.of(rs.getDouble(1));
}
return OptionalDouble.empty();
}
};
/** The Constant SINGLE_BIG_DECIMAL_EXTRACTOR. */
private static final ResultExtractor> SINGLE_BIG_DECIMAL_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return Nullable.of(rs.getBigDecimal(1));
}
return Nullable.empty();
}
};
/** The Constant SINGLE_STRING_EXTRACTOR. */
private static final ResultExtractor> SINGLE_STRING_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return Nullable.of(rs.getString(1));
}
return Nullable.empty();
}
};
/** The Constant SINGLE_DATE_EXTRACTOR. */
private static final ResultExtractor> SINGLE_DATE_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return Nullable.of(rs.getDate(1));
}
return Nullable.empty();
}
};
/** The Constant SINGLE_TIME_EXTRACTOR. */
private static final ResultExtractor> SINGLE_TIME_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return Nullable.of(rs.getTime(1));
}
return Nullable.empty();
}
};
/** The Constant SINGLE_TIMESTAMP_EXTRACTOR. */
private static final ResultExtractor> SINGLE_TIMESTAMP_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable apply(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
return Nullable.of(rs.getTimestamp(1));
}
return Nullable.empty();
}
};
/** The Constant factor. */
private static final int factor = Math.min(Math.max(1, IOUtil.MAX_MEMORY_IN_MB / 1024), 8);
/** The Constant CACHED_SQL_LENGTH. */
private static final int CACHED_SQL_LENGTH = 1024 * factor;
/** The Constant SQL_CACHE_SIZE. */
private static final int SQL_CACHE_SIZE = 1000 * factor;
/** The Constant _sqlColumnLabelPool. */
private static final Map> _sqlColumnLabelPool = new ConcurrentHashMap<>();
/** The table column name pool. */
private final Map> _tableColumnNamePool = new ConcurrentHashMap<>();
/** The ds. */
private final DataSource _ds;
/** The dsm. */
private final DataSourceManager _dsm;
/** The dss. */
private final DataSourceSelector _dss;
/** The jdbc settings. */
private final JdbcSettings _jdbcSettings;
/** The sql mapper. */
private final SQLMapper _sqlMapper;
/** The naming policy. */
private final NamingPolicy _namingPolicy;
/** The async executor. */
private final AsyncExecutor _asyncExecutor;
/** The is read only. */
private final boolean _isReadOnly;
/** The db proudct name. */
private final String _dbProudctName;
/** The db proudct version. */
private final String _dbProudctVersion;
/** The db version. */
private final DBVersion _dbVersion;
/** The default isolation level. */
private final IsolationLevel _defaultIsolationLevel;
/** The async SQL executor. */
private final AsyncSQLExecutor _asyncSQLExecutor;
@SuppressWarnings("rawtypes")
private final Map, Mapper> mapperPool = new ConcurrentHashMap<>();
@SuppressWarnings("rawtypes")
private final Map, MapperL> mapperLPool = new ConcurrentHashMap<>();
@SuppressWarnings("rawtypes")
private final Map, MapperEx> mapperExPool = new ConcurrentHashMap<>();
@SuppressWarnings("rawtypes")
private final Map, MapperLEx> mapperExLPool = new ConcurrentHashMap<>();
/**
* Instantiates a new SQL executor.
*
* @param dataSource
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final DataSource dataSource) {
this(dataSource, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSource
* @param jdbcSettings
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final DataSource dataSource, final JdbcSettings jdbcSettings) {
this(dataSource, jdbcSettings, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper) {
this(dataSource, jdbcSettings, sqlMapper, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy) {
this(dataSource, jdbcSettings, sqlMapper, namingPolicy, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @param asyncExecutor
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy,
final AsyncExecutor asyncExecutor) {
this(null, dataSource, jdbcSettings, sqlMapper, namingPolicy, asyncExecutor, false);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager) {
this(dataSourceManager, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @param jdbcSettings
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager, final JdbcSettings jdbcSettings) {
this(dataSourceManager, jdbcSettings, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @param jdbcSettings
* @param sqlMapper
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper) {
this(dataSourceManager, jdbcSettings, sqlMapper, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy) {
this(dataSourceManager, jdbcSettings, sqlMapper, namingPolicy, null);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @param asyncExecutor
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy,
final AsyncExecutor asyncExecutor) {
this(dataSourceManager, null, jdbcSettings, sqlMapper, namingPolicy, asyncExecutor, false);
}
/**
* Instantiates a new SQL executor.
*
* @param dataSourceManager
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @param asyncExecutor
* @param isReadOnly
*/
protected SQLExecutor(final DataSourceManager dataSourceManager, final DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper,
final NamingPolicy namingPolicy, final AsyncExecutor asyncExecutor, final boolean isReadOnly) {
if (dataSourceManager == null) {
this._ds = dataSource;
this._dsm = null;
this._dss = null;
} else {
this._ds = dataSourceManager.getPrimaryDataSource();
this._dsm = dataSourceManager;
this._dss = dataSourceManager.getDataSourceSelector();
}
this._jdbcSettings = (jdbcSettings == null) ? JdbcSettings.create() : jdbcSettings.copy();
if (_jdbcSettings.getBatchSize() == 0) {
_jdbcSettings.setBatchSize(JdbcSettings.DEFAULT_BATCH_SIZE);
}
_jdbcSettings.freeze();
this._sqlMapper = sqlMapper == null ? new SQLMapper() : sqlMapper;
this._namingPolicy = namingPolicy == null ? NamingPolicy.LOWER_CASE_WITH_UNDERSCORE : namingPolicy;
this._asyncExecutor = asyncExecutor == null ? new AsyncExecutor(8, Math.max(32, IOUtil.CPU_CORES), 180L, TimeUnit.SECONDS) : asyncExecutor;
this._isReadOnly = isReadOnly;
int originalIsolationLevel;
Connection conn = getConnection();
try {
_dbProudctName = conn.getMetaData().getDatabaseProductName();
_dbProudctVersion = conn.getMetaData().getDatabaseProductVersion();
_dbVersion = JdbcUtil.getDBVersion(conn);
originalIsolationLevel = conn.getTransactionIsolation();
} catch (SQLException e) {
throw new UncheckedSQLException(e);
} finally {
closeConnection(conn);
}
final IsolationLevel tmp = this._ds instanceof SQLDataSource ? ((SQLDataSource) this._ds).getDefaultIsolationLevel() : IsolationLevel.DEFAULT;
_defaultIsolationLevel = tmp == IsolationLevel.DEFAULT ? IsolationLevel.valueOf(originalIsolationLevel) : tmp;
this._asyncSQLExecutor = new AsyncSQLExecutor(this, _asyncExecutor);
}
// public static SQLExecutor create(final String dataSourceFile) {
// return new SQLExecutor(JdbcUtil.createDataSourceManager(dataSourceFile));
// }
//
// public static SQLExecutor create(final InputStream dataSourceInputStream) {
// return new SQLExecutor(JdbcUtil.createDataSourceManager(dataSourceInputStream));
// }
//
// public static SQLExecutor create(final String url, final String user, final String password) {
// return new SQLExecutor(JdbcUtil.createDataSource(url, user, password));
// }
//
// public static SQLExecutor create(final String driver, final String url, final String user, final String password) {
// return new SQLExecutor(JdbcUtil.createDataSource(driver, url, user, password));
// }
//
// public static SQLExecutor create(final Class extends Driver> driverClass, final String url, final String user, final String password) {
// return new SQLExecutor(JdbcUtil.createDataSource(driverClass, url, user, password));
// }
//
// /**
// *
// * @param props refer to Connection.xsd for the supported properties.
// * @return
// */
// public static SQLExecutor create(final Map props) {
// return new SQLExecutor(JdbcUtil.createDataSource(props));
// }
//
// public static SQLExecutor create(final DataSource sqlDataSource) {
// return new SQLExecutor(JdbcUtil.wrap(sqlDataSource));
// }
//
// public SQLMapper sqlMapper() {
// return _sqlMapper;
// }
/**
*
* @param url
* @param user
* @param password
* @return
*/
@Beta
public static SQLExecutor create(final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(url, user, password));
}
/**
*
* @param driver
* @param url
* @param user
* @param password
* @return
*/
@Beta
public static SQLExecutor create(final String driver, final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(driver, url, user, password));
}
/**
*
* @param driverClass
* @param url
* @param user
* @param password
* @return
*/
@Beta
public static SQLExecutor create(final Class extends Driver> driverClass, final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(driverClass, url, user, password));
}
/**
*
* @param driverClass
* @param url
* @param user
* @param password
* @return
*/
@Beta
public static SQLExecutor create(final DataSource dataSource) {
return new SQLExecutor(dataSource);
}
/**
*
* @param
* @param
* @param entityClass the id class
* @param idClass the id class type of target id property.
* It should be {@code Void} class if there is no id property defined for the target entity, or {@code EntityId} class if there is zero or multiple id properties.
* @return
*/
public Mapper mapper(final Class entityClass, final Class idClass) {
synchronized (mapperPool) {
Mapper mapper = mapperPool.get(entityClass);
if (mapper == null) {
mapper = new Mapper<>(entityClass, idClass, this, this._namingPolicy);
mapperPool.put(entityClass, mapper);
} else if (!mapper.idClass.equals(idClass)) {
throw new IllegalArgumentException("Mapper for entity \"" + ClassUtil.getSimpleClassName(entityClass)
+ "\" has already been created with different id class: " + mapper.idClass);
}
return mapper;
}
}
public MapperL mapper(final Class entityClass) {
synchronized (mapperLPool) {
MapperL mapper = mapperLPool.get(entityClass);
if (mapper == null) {
mapper = new MapperL<>(entityClass, this, this._namingPolicy);
mapperLPool.put(entityClass, mapper);
}
return mapper;
}
}
/**
*
* @param
* @param
* @param entityClass the id class
* @param idClass the id class type of target id property.
* It should be {@code Void} class if there is no id property defined for the target entity, or {@code EntityId} class if there is zero or multiple id properties.
* @return
*/
public MapperEx mapperEx(final Class entityClass, final Class idClass) {
synchronized (mapperExPool) {
MapperEx mapper = mapperExPool.get(entityClass);
if (mapper == null) {
mapper = new MapperEx<>(entityClass, idClass, this, this._namingPolicy);
mapperExPool.put(entityClass, mapper);
} else if (!mapper.idClass.equals(idClass)) {
throw new IllegalArgumentException("MapperEx for entity \"" + ClassUtil.getSimpleClassName(entityClass)
+ "\" has already been created with different id class: " + mapper.idClass);
}
return mapper;
}
}
public MapperLEx mapperEx(final Class entityClass) {
synchronized (mapperExLPool) {
MapperLEx mapper = mapperExLPool.get(entityClass);
if (mapper == null) {
mapper = new MapperLEx<>(entityClass, this, this._namingPolicy);
mapperExLPool.put(entityClass, mapper);
}
return mapper;
}
}
/**
*
* @return
*/
public AsyncSQLExecutor async() {
return _asyncSQLExecutor;
}
/**
*
* @return
*/
public DataSource dataSource() {
return _ds;
}
/**
*
* @return
*/
public JdbcSettings jdbcSettings() {
return _jdbcSettings;
}
/**
* Db proudct name.
*
* @return
*/
public String dbProudctName() {
return _dbProudctName;
}
/**
* Db proudct version.
*
* @return
*/
public String dbProudctVersion() {
return _dbProudctVersion;
}
/**
*
* @return
*/
public DBVersion dbVersion() {
return _dbVersion;
}
/**
*
* @param
* @param sql
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final String sql, final Object... parameters) throws UncheckedSQLException {
return insert(sql, StatementSetter.DEFAULT, parameters);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final String sql, final StatementSetter statementSetter, final Object... parameters) throws UncheckedSQLException {
return insert(sql, statementSetter, null, parameters);
}
/**
*
* @param
* @param sql
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final String sql, final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return insert(sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return insert(sql, statementSetter, null, jdbcSettings, parameters);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param autoGeneratedKeyExtractor
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final String sql, final StatementSetter statementSetter, final JdbcUtil.BiRowMapper autoGeneratedKeyExtractor,
final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return insert(null, sql, statementSetter, autoGeneratedKeyExtractor, jdbcSettings, parameters);
}
/**
*
* @param
* @param conn
* @param sql
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final Connection conn, final String sql, final Object... parameters) throws UncheckedSQLException {
return insert(conn, sql, StatementSetter.DEFAULT, parameters);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final Connection conn, final String sql, final StatementSetter statementSetter, final Object... parameters)
throws UncheckedSQLException {
return insert(conn, sql, statementSetter, null, parameters);
}
/**
*
* @param
* @param conn
* @param sql
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public final ID insert(final Connection conn, final String sql, final JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return insert(conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final ID insert(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return insert(conn, sql, statementSetter, null, jdbcSettings, parameters);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param autoGeneratedKeyExtractor
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
* @see #batchInsert(Connection, String, StatementSetter, JdbcSettings, String, Object[])
*/
@SuppressWarnings({ "unchecked", "deprecation" })
@SafeVarargs
public final ID insert(final Connection conn, final String sql, StatementSetter statementSetter, JdbcUtil.BiRowMapper autoGeneratedKeyExtractor,
JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
final ParsedSql parsedSql = getParsedSql(sql);
final boolean isEntityOrMapParameter = isEntityOrMapParameter(parsedSql, parameters);
final boolean isEntity = isEntityOrMapParameter && ClassUtil.isEntity(parameters[0].getClass());
final Collection idPropNames = isEntity ? ClassUtil.getIdFieldNames(parameters[0].getClass()) : null;
final boolean autoGeneratedKeys = isEntity == false || (N.notNullOrEmpty(idPropNames) && !parsedSql.getNamedParameters().containsAll(idPropNames));
statementSetter = checkStatementSetter(parsedSql, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, parsedSql, _sqlMapper.getAttrs(sql));
autoGeneratedKeyExtractor = checkGeneratedKeysExtractor(autoGeneratedKeyExtractor, jdbcSettings, parameters);
DataSource ds = null;
Connection localConn = null;
Object id = null;
PreparedStatement stmt = null;
try {
ds = getDataSource(parsedSql.getParameterizedSql(), parameters, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.INSERT);
stmt = prepareStatement(ds, localConn, parsedSql, statementSetter, jdbcSettings, autoGeneratedKeys, false, parameters);
id = executeInsert(parsedSql, stmt, autoGeneratedKeyExtractor, autoGeneratedKeys);
} catch (SQLException e) {
String msg = ExceptionUtil.getMessage(e) + ". [SQL] " + parsedSql.sql();
throw new UncheckedSQLException(msg, e);
} finally {
close(stmt);
close(localConn, conn, ds);
}
if (isEntityOrMapParameter && isEntity) {
final Object entity = parameters[0];
if (id == null) {
id = getIdGetter(entity).apply(entity);
} else {
getIdSetter(entity).accept(id, entity);
}
if (entity instanceof DirtyMarker) {
DirtyMarkerUtil.dirtyPropNames((DirtyMarker) parameters[0]).clear();
}
}
return (ID) id;
}
static JdbcUtil.BiRowMapper checkGeneratedKeysExtractor(JdbcUtil.BiRowMapper autoGeneratedKeyExtractor, final JdbcSettings jdbcSettings,
final Object... parameters) {
if ((autoGeneratedKeyExtractor == null || autoGeneratedKeyExtractor == JdbcUtil.SINGLE_BI_GENERATED_KEY_EXTRACTOR
|| autoGeneratedKeyExtractor == JdbcUtil.MULTI_BI_GENERATED_KEY_EXTRACTOR) //
&& N.notNullOrEmpty(parameters) && parameters.length == 1 && parameters[0] != null && ClassUtil.isEntity(parameters[0].getClass())) {
return (JdbcUtil.BiRowMapper) JdbcUtil.getIdGeneratorGetterSetter(JdbcUtil.CrudDao.class, parameters[0].getClass(),
NamingPolicy.LOWER_CASE_WITH_UNDERSCORE, EntityId.class)._1;
} else if (autoGeneratedKeyExtractor == null) {
if (jdbcSettings != null && ((N.notNullOrEmpty(jdbcSettings.getReturnedColumnIndexes()) && jdbcSettings.getReturnedColumnIndexes().length > 1)
|| (N.notNullOrEmpty(jdbcSettings.getReturnedColumnNames()) && jdbcSettings.getReturnedColumnNames().length > 1))) {
return (JdbcUtil.BiRowMapper) JdbcUtil.MULTI_BI_GENERATED_KEY_EXTRACTOR;
} else {
return (JdbcUtil.BiRowMapper) JdbcUtil.SINGLE_BI_GENERATED_KEY_EXTRACTOR;
}
}
return autoGeneratedKeyExtractor;
}
static Function getIdGetter(final Object entity) {
return (Function) JdbcUtil.getIdGeneratorGetterSetter(JdbcUtil.CrudDao.class, entity == null ? null : entity.getClass(),
NamingPolicy.LOWER_CASE_WITH_UNDERSCORE, EntityId.class)._2;
}
static BiConsumer getIdSetter(final Object entity) {
return (BiConsumer) JdbcUtil.getIdGeneratorGetterSetter(JdbcUtil.CrudDao.class, entity == null ? null : entity.getClass(),
NamingPolicy.LOWER_CASE_WITH_UNDERSCORE, EntityId.class)._3;
}
protected ID executeInsert(final ParsedSql parsedSql, final PreparedStatement stmt, final JdbcUtil.BiRowMapper autoGeneratedKeyExtractor,
final boolean autoGeneratedKeys) throws SQLException {
if (_isReadOnly) {
throw new RuntimeException("This SQL Executor is configured for read-only");
}
JdbcUtil.executeUpdate(stmt);
ID id = null;
if (autoGeneratedKeys) {
ResultSet rs = null;
try {
rs = stmt.getGeneratedKeys();
id = rs.next() ? autoGeneratedKeyExtractor.apply(rs, JdbcUtil.getColumnLabelList(rs)) : null;
} catch (SQLException e) {
logger.error("Failed to retrieve the auto-generated Ids", e);
} finally {
close(rs);
}
}
return id;
}
/**
*
* @param
* @param sql
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final String sql, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, StatementSetter.DEFAULT, parametersList);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final String sql, final StatementSetter statementSetter, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, statementSetter, null, parametersList);
}
/**
*
* @param
* @param sql
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final String sql, final JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchInsert(sql, statementSetter, null, jdbcSettings, parametersList);
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param autoGeneratedKeyExtractor
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final String sql, final StatementSetter statementSetter, final JdbcUtil.BiRowMapper autoGeneratedKeyExtractor,
final JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
return batchInsert(null, sql, statementSetter, autoGeneratedKeyExtractor, jdbcSettings, parametersList);
}
/**
*
* @param
* @param conn
* @param sql
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final Connection conn, final String sql, final List> parametersList) throws UncheckedSQLException {
return batchInsert(conn, sql, StatementSetter.DEFAULT, parametersList);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final Connection conn, final String sql, final StatementSetter statementSetter, final List> parametersList)
throws UncheckedSQLException {
return batchInsert(conn, sql, statementSetter, null, parametersList);
}
/**
*
* @param
* @param conn
* @param sql
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final Connection conn, final String sql, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchInsert(conn, sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public List batchInsert(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings,
final List> parametersList) throws UncheckedSQLException {
return batchInsert(conn, sql, statementSetter, null, jdbcSettings, parametersList);
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param autoGeneratedKeyExtractor
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SuppressWarnings("deprecation")
public List batchInsert(final Connection conn, final String sql, StatementSetter statementSetter,
JdbcUtil.BiRowMapper autoGeneratedKeyExtractor, JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
N.checkArgNotNullOrEmpty(parametersList, "parametersList");
final ParsedSql parsedSql = getParsedSql(sql);
final Object parameters_0 = parametersList.get(0);
final boolean isEntityOrMapParameter = isEntityOrMapParameter(parsedSql, parameters_0);
final boolean isEntity = isEntityOrMapParameter && ClassUtil.isEntity(parameters_0.getClass());
final Collection idPropNames = isEntity ? ClassUtil.getIdFieldNames(parameters_0.getClass()) : null;
final boolean autoGeneratedKeys = isEntity == false || (N.notNullOrEmpty(idPropNames) && !parsedSql.getNamedParameters().containsAll(idPropNames));
statementSetter = checkStatementSetter(parsedSql, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, parsedSql, _sqlMapper.getAttrs(sql));
autoGeneratedKeyExtractor = checkGeneratedKeysExtractor(autoGeneratedKeyExtractor, jdbcSettings, parametersList.get(0));
final int len = parametersList.size();
final int batchSize = getBatchSize(jdbcSettings);
List ids = new ArrayList<>(len);
DataSource ds = null;
Connection localConn = null;
PreparedStatement stmt = null;
int originalIsolationLevel = 0;
boolean autoCommit = true;
final Object[] parameters = new Object[1];
try {
ds = getDataSource(parsedSql.getParameterizedSql(), parametersList, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.INSERT);
try {
originalIsolationLevel = localConn.getTransactionIsolation();
autoCommit = localConn.getAutoCommit();
} catch (SQLException e) {
close(localConn, conn, ds);
throw new UncheckedSQLException(e);
}
if ((conn == null) && (len > batchSize)) {
localConn.setAutoCommit(false);
setIsolationLevel(jdbcSettings, localConn);
}
stmt = prepareStatement(ds, localConn, parsedSql, statementSetter, jdbcSettings, autoGeneratedKeys, true, parametersList);
if (len <= batchSize) {
for (int i = 0; i < len; i++) {
parameters[0] = parametersList.get(i);
statementSetter.accept(parsedSql, stmt, parameters);
stmt.addBatch();
}
executeBatchInsert(ids, parsedSql, stmt, autoGeneratedKeyExtractor, autoGeneratedKeys);
} else {
int num = 0;
for (int i = 0; i < len; i++) {
parameters[0] = parametersList.get(i);
statementSetter.accept(parsedSql, stmt, parameters);
stmt.addBatch();
num++;
if ((num % batchSize) == 0) {
executeBatchInsert(ids, parsedSql, stmt, autoGeneratedKeyExtractor, autoGeneratedKeys);
}
}
if ((num % batchSize) > 0) {
executeBatchInsert(ids, parsedSql, stmt, autoGeneratedKeyExtractor, autoGeneratedKeys);
}
}
if ((conn == null) && (len > batchSize) && autoCommit == true) {
localConn.commit();
}
} catch (SQLException e) {
if ((conn == null) && (len > batchSize) && autoCommit == true) {
if (logger.isWarnEnabled()) {
logger.warn("Trying to roll back ...");
}
try {
localConn.rollback();
if (logger.isWarnEnabled()) {
logger.warn("succeeded to roll back");
}
} catch (SQLException e1) {
logger.error("Failed to roll back", e1);
}
}
String msg = ExceptionUtil.getMessage(e) + ". [SQL] " + parsedSql.sql();
throw new UncheckedSQLException(msg, e);
} finally {
if ((conn == null) && (len > batchSize)) {
try {
localConn.setAutoCommit(autoCommit);
localConn.setTransactionIsolation(originalIsolationLevel);
} catch (SQLException e) {
logger.error("Failed to reset AutoCommit", e);
}
}
close(stmt);
close(localConn, conn, ds);
}
if (N.notNullOrEmpty(ids) && Stream.of(ids).allMatch(Fn.isNull())) {
ids = new ArrayList<>();
}
if (N.notNullOrEmpty(ids) && ids.size() != parametersList.size()) {
if (logger.isWarnEnabled()) {
logger.warn("The size of returned id list: {} is different from the size of input parameter list: {}", ids.size(), parametersList.size());
}
}
if (parametersList.get(0) != null && isEntityOrMapParameter(parsedSql, parametersList.get(0)) && ClassUtil.isEntity(parametersList.get(0).getClass())) {
final Object entity = parametersList.get(0);
if (N.isNullOrEmpty(ids)) {
final Function idGetter = getIdGetter(entity);
ids = Stream.of(parametersList).map(idGetter).toList();
} else {
final BiConsumer idSetter = getIdSetter(entity);
if (ids.size() == len) {
for (int i = 0; i < len; i++) {
idSetter.accept(ids.get(i), parametersList.get(i));
}
} else {
if (logger.isWarnEnabled()) {
logger.warn(
"Failed to set the returned id property to entity/map. because the size of returned key not equals the lenght of the input arrray");
}
}
}
if (entity instanceof DirtyMarker) {
for (Object e : parametersList) {
DirtyMarkerUtil.dirtyPropNames((DirtyMarker) e).clear();
}
}
}
return ids;
}
/**
* Sets the isolation level.
*
* @param jdbcSettings
* @param localConn
* @throws SQLException the SQL exception
*/
private void setIsolationLevel(JdbcSettings jdbcSettings, Connection localConn) throws SQLException {
final int isolationLevel = jdbcSettings.getIsolationLevel() == null || jdbcSettings.getIsolationLevel() == IsolationLevel.DEFAULT
? _defaultIsolationLevel.intValue()
: jdbcSettings.getIsolationLevel().intValue();
if (isolationLevel == localConn.getTransactionIsolation()) {
// ignore.
} else {
localConn.setTransactionIsolation(isolationLevel);
}
}
/**
* Execute batch insert.
*
* @param
* @param resultIdList
* @param parsedSql
* @param stmt
* @param autoGeneratedKeyExtractor
* @param autoGeneratedKeys
* @throws SQLException the SQL exception
*/
protected void executeBatchInsert(final List resultIdList, final ParsedSql parsedSql, final PreparedStatement stmt,
final JdbcUtil.BiRowMapper autoGeneratedKeyExtractor, final boolean autoGeneratedKeys) throws SQLException {
if (_isReadOnly) {
throw new RuntimeException("This SQL Executor is configured for read-only");
}
executeBatch(stmt);
if (autoGeneratedKeys) {
ResultSet rs = null;
try {
rs = stmt.getGeneratedKeys();
final List columnLabels = JdbcUtil.getColumnLabelList(rs);
while (rs.next()) {
resultIdList.add(autoGeneratedKeyExtractor.apply(rs, columnLabels));
}
} catch (SQLException e) {
logger.error("Failed to retrieve the auto-generated Ids", e);
} finally {
close(rs);
}
}
}
private int[] executeBatch(final PreparedStatement stmt) throws SQLException {
return JdbcUtil.executeBatch(stmt);
}
/**
*
* @param sql
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final String sql, final Object... parameters) throws UncheckedSQLException {
return update(sql, StatementSetter.DEFAULT, parameters);
}
/**
*
* @param sql
* @param statementSetter
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final String sql, final StatementSetter statementSetter, final Object... parameters) throws UncheckedSQLException {
return update(sql, statementSetter, null, parameters);
}
/**
*
* @param sql
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final String sql, final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return update(sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return update(null, sql, statementSetter, jdbcSettings, parameters);
}
/**
*
* @param conn
* @param sql
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final Connection conn, final String sql, final Object... parameters) throws UncheckedSQLException {
return update(conn, sql, StatementSetter.DEFAULT, parameters);
}
/**
*
* @param conn
* @param sql
* @param statementSetter
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final Connection conn, final String sql, final StatementSetter statementSetter, final Object... parameters)
throws UncheckedSQLException {
return update(conn, sql, statementSetter, null, parameters);
}
/**
*
* @param conn
* @param sql
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
@SafeVarargs
public final int update(final Connection conn, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return update(conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
* @throws UncheckedSQLException the unchecked SQL exception
* @see #batchUpdate(Connection, String, StatementSetter, JdbcSettings, Object[])
*/
@SafeVarargs
public final int update(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
final ParsedSql parsedSql = getParsedSql(sql);
statementSetter = checkStatementSetter(parsedSql, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, parsedSql, _sqlMapper.getAttrs(sql));
DataSource ds = null;
Connection localConn = null;
PreparedStatement stmt = null;
try {
ds = getDataSource(parsedSql.getParameterizedSql(), parameters, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.UPDATE);
stmt = prepareStatement(ds, localConn, parsedSql, statementSetter, jdbcSettings, false, false, parameters);
final int result = executeUpdate(parsedSql, stmt);
if (isEntityOrMapParameter(parsedSql, parameters)) {
if (parameters[0] instanceof DirtyMarker) {
DirtyMarkerUtil.markDirty((DirtyMarker) parameters[0], parsedSql.getNamedParameters(), false);
}
}
return result;
} catch (SQLException e) {
String msg = ExceptionUtil.getMessage(e) + ". [SQL] " + parsedSql.sql();
throw new UncheckedSQLException(msg, e);
} finally {
close(stmt);
close(localConn, conn, ds);
}
}
/**
*
* @param parsedSql
* @param stmt
* @return
* @throws SQLException the SQL exception
*/
protected int executeUpdate(final ParsedSql parsedSql, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new RuntimeException("This SQL Executor is configured for read-only");
}
return JdbcUtil.executeUpdate(stmt);
}
/**
*
* @param sql
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final String sql, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, StatementSetter.DEFAULT, parametersList);
}
/**
*
* @param sql
* @param statementSetter
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final String sql, final StatementSetter statementSetter, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, statementSetter, null, parametersList);
}
/**
*
* @param sql
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final String sql, final JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
/**
*
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchUpdate(null, sql, statementSetter, jdbcSettings, parametersList);
}
/**
*
* @param conn
* @param sql
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final Connection conn, final String sql, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(conn, sql, StatementSetter.DEFAULT, parametersList);
}
/**
*
* @param conn
* @param sql
* @param statementSetter
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final Connection conn, final String sql, final StatementSetter statementSetter, final List> parametersList)
throws UncheckedSQLException {
return batchUpdate(conn, sql, statementSetter, null, parametersList);
}
/**
*
* @param conn
* @param sql
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int batchUpdate(final Connection conn, final String sql, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchUpdate(conn, sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
/**
*
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parametersList
* @return
* @throws UncheckedSQLException the unchecked SQL exception
* @see #batchUpdate(Connection, String, StatementSetter, JdbcSettings, Object[])
*/
public int batchUpdate(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
final ParsedSql parsedSql = getParsedSql(sql);
statementSetter = checkStatementSetter(parsedSql, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, parsedSql, _sqlMapper.getAttrs(sql));
final int len = parametersList.size();
final int batchSize = getBatchSize(jdbcSettings);
DataSource ds = null;
Connection localConn = null;
PreparedStatement stmt = null;
int originalIsolationLevel = 0;
boolean autoCommit = true;
try {
ds = getDataSource(parsedSql.getParameterizedSql(), parametersList, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.UPDATE);
try {
originalIsolationLevel = localConn.getTransactionIsolation();
autoCommit = localConn.getAutoCommit();
} catch (SQLException e) {
close(localConn, conn, ds);
throw new UncheckedSQLException(e);
}
if ((conn == null) && (len > batchSize)) {
localConn.setAutoCommit(false);
setIsolationLevel(jdbcSettings, localConn);
}
stmt = prepareStatement(ds, localConn, parsedSql, statementSetter, jdbcSettings, false, true, parametersList);
int result = 0;
final Object[] parameters = new Object[1];
if (len <= batchSize) {
for (int i = 0; i < len; i++) {
parameters[0] = parametersList.get(i);
statementSetter.accept(parsedSql, stmt, parameters);
stmt.addBatch();
}
result += executeBatchUpdate(parsedSql, stmt);
} else {
int num = 0;
for (int i = 0; i < len; i++) {
parameters[0] = parametersList.get(i);
statementSetter.accept(parsedSql, stmt, parameters);
stmt.addBatch();
num++;
if ((num % batchSize) == 0) {
result += executeBatchUpdate(parsedSql, stmt);
}
}
if ((num % batchSize) > 0) {
result += executeBatchUpdate(parsedSql, stmt);
}
}
if ((conn == null) && (len > batchSize) && autoCommit == true) {
localConn.commit();
}
if (N.firstOrNullIfEmpty(parametersList) instanceof DirtyMarker) {
for (Object e : parametersList) {
DirtyMarkerUtil.markDirty((DirtyMarker) e, parsedSql.getNamedParameters(), false);
}
}
return result;
} catch (SQLException e) {
if ((conn == null) && (len > batchSize) && autoCommit == true) {
if (logger.isWarnEnabled()) {
logger.warn("Trying to roll back ...");
}
try {
localConn.rollback();
if (logger.isWarnEnabled()) {
logger.warn("succeeded to roll back");
}
} catch (SQLException e1) {
logger.error("Failed to roll back", e1);
}
}
String msg = ExceptionUtil.getMessage(e) + ". [SQL] " + parsedSql.sql();
throw new UncheckedSQLException(msg, e);
} finally {
if ((conn == null) && (len > batchSize)) {
try {
localConn.setAutoCommit(autoCommit);
localConn.setTransactionIsolation(originalIsolationLevel);
} catch (SQLException e) {
logger.error("Failed to reset AutoCommit", e);
}
}
close(stmt);
close(localConn, conn, ds);
}
}
/**
* Execute batch update.
*
* @param parsedSql
* @param stmt
* @return
* @throws SQLException the SQL exception
*/
protected int executeBatchUpdate(final ParsedSql parsedSql, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new RuntimeException("This SQL Executor is configured for read-only");
}
final int[] results = executeBatch(stmt);
if ((results == null) || (results.length == 0)) {
return 0;
}
int sum = 0;
for (int i = 0; i < results.length; i++) {
sum += results[i];
}
return sum;
}
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// int update(final EntityId entityId, final Map props) {
// return update(null, entityId, props);
// }
//
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// int update(final Connection conn, final EntityId entityId, final Map props) {
// final Pair2 pair = generateUpdateSQL(entityId, props);
//
// return update(conn, sp.sql, sp.parameters);
// }
//
// private Pair2 generateUpdateSQL(final EntityId entityId, final Map props) {
// final Condition cond = EntityManagerUtil.entityId2Condition(entityId);
// final NamingPolicy namingPolicy = _jdbcSettings.getNamingPolicy();
//
// if (namingPolicy == null) {
// return NE.update(entityId.entityName()).set(props).where(cond).pair();
// }
//
// switch (namingPolicy) {
// case LOWER_CASE_WITH_UNDERSCORE: {
// return NE.update(entityId.entityName()).set(props).where(cond).pair();
// }
//
// case UPPER_CASE_WITH_UNDERSCORE: {
// return NE2.update(entityId.entityName()).set(props).where(cond).pair();
// }
//
// case CAMEL_CASE: {
// return NE3.update(entityId.entityName()).set(props).where(cond).pair();
// }
//
// default:
// throw new IllegalArgumentException("Unsupported naming policy");
// }
// }
//
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// int delete(final EntityId entityId) {
// return delete(null, entityId);
// }
//
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// int delete(final Connection conn, final EntityId entityId) {
// final Pair2 pair = generateDeleteSQL(entityId);
//
// return update(conn, sp.sql, sp.parameters);
// }
//
// private Pair2 generateDeleteSQL(final EntityId entityId) {
// final Condition cond = EntityManagerUtil.entityId2Condition(entityId);
// final NamingPolicy namingPolicy = _jdbcSettings.getNamingPolicy();
//
// if (namingPolicy == null) {
// return NE.deleteFrom(entityId.entityName()).where(cond).pair();
// }
//
// switch (namingPolicy) {
// case LOWER_CASE_WITH_UNDERSCORE: {
// return NE.deleteFrom(entityId.entityName()).where(cond).pair();
// }
//
// case UPPER_CASE_WITH_UNDERSCORE: {
// return NE2.deleteFrom(entityId.entityName()).where(cond).pair();
// }
//
// case CAMEL_CASE: {
// return NE3.deleteFrom(entityId.entityName()).where(cond).pair();
// }
//
// default:
// throw new IllegalArgumentException("Unsupported naming policy");
// }
// }
//
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// boolean exists(final EntityId entityId) {
// return exists(null, entityId);
// }
//
// // mess up. To uncomment this method, also need to modify getNamingPolicy/setNamingPolicy in JdbcSettings.
// boolean exists(final Connection conn, final EntityId entityId) {
// final Pair2 pair = generateQuerySQL(entityId, NE._1_list);
//
// return query(conn, sp.sql, StatementSetter.DEFAULT, EXISTS_RESULT_SET_EXTRACTOR, null, sp.parameters);
// }
/**
*
* @param sql
* @param parameters
* @return true, if successful
*/
@SafeVarargs
public final boolean exists(final String sql, final Object... parameters) {
return exists(null, sql, parameters);
}
/**
*
* @param conn
* @param sql
* @param parameters
* @return true, if successful
*/
@SafeVarargs
public final boolean exists(final Connection conn, final String sql, final Object... parameters) {
return query(conn, sql, StatementSetter.DEFAULT, EXISTS_RESULT_SET_EXTRACTOR, null, parameters);
}
/**
*
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @deprecated may be misused and it's inefficient.
*/
@Deprecated
@SafeVarargs
final int count(final String sql, final Object... parameters) {
return count(null, sql, parameters);
}
/**
*
* @param conn
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @deprecated may be misused and it's inefficient.
*/
@Deprecated
@SafeVarargs
final int count(final Connection conn, final String sql, final Object... parameters) {
return query(conn, sql, StatementSetter.DEFAULT, COUNT_RESULT_SET_EXTRACTOR, null, parameters);
}
/**
*
* @param
* @param targetClass
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, sql, parameters));
}
/**
*
* @param
* @param targetClass
* @param sql
* @param statementSetter
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, sql, statementSetter, parameters));
}
/**
*
* @param
* @param targetClass
* @param sql
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, sql, jdbcSettings, parameters));
}
/**
*
* @param
* @param targetClass
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings,
final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, sql, statementSetter, jdbcSettings, parameters));
}
/**
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, conn, sql, parameters));
}
/**
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, conn, sql, statementSetter, parameters));
}
/**
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final JdbcSettings jdbcSettings,
final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, conn, sql, jdbcSettings, parameters));
}
/**
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
JdbcSettings jdbcSettings, final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(targetClass, conn, sql, statementSetter, jdbcSettings, parameters));
}
/**
*
* @param
* @param sql
* @param rowMapper
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final String sql, final JdbcUtil.RowMapper rowMapper, final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(sql, rowMapper, parameters));
}
/**
*
* @param
* @param sql
* @param statementSetter
* @param rowMapper
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
public final Optional get(final String sql, final StatementSetter statementSetter, final JdbcUtil.RowMapper rowMapper, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(sql, statementSetter, rowMapper, parameters));
}
/**
*
* @param
* @param sql
* @param rowMapper
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
public final Optional get(final String sql, final JdbcUtil.RowMapper rowMapper, final JdbcSettings jdbcSettings, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(sql, rowMapper, jdbcSettings, parameters));
}
/**
*
*
* @param
* @param sql
* @param statementSetter
* @param rowMapper
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final String sql, final StatementSetter statementSetter, final JdbcUtil.RowMapper rowMapper,
final JdbcSettings jdbcSettings, final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(sql, statementSetter, rowMapper, jdbcSettings, parameters));
}
/**
*
*
* @param
* @param conn
* @param sql
* @param rowMapper
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final JdbcUtil.RowMapper rowMapper, final Object... parameters)
throws DuplicatedResultException {
return Optional.ofNullable(gett(conn, sql, rowMapper, parameters));
}
/**
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param rowMapper
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final StatementSetter statementSetter, final JdbcUtil.RowMapper rowMapper,
final Object... parameters) {
return Optional.ofNullable(gett(conn, sql, statementSetter, rowMapper, parameters));
}
/**
*
* @param
* @param conn
* @param sql
* @param rowMapper
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final JdbcUtil.RowMapper rowMapper, JdbcSettings jdbcSettings,
final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(conn, sql, rowMapper, jdbcSettings, parameters));
}
/**
*
*
* @param
* @param conn
* @param sql
* @param statementSetter
* @param rowMapper
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final StatementSetter statementSetter, final JdbcUtil.RowMapper rowMapper,
final JdbcSettings jdbcSettings, final Object... parameters) throws DuplicatedResultException {
return Optional.ofNullable(gett(conn, sql, statementSetter, rowMapper, jdbcSettings, parameters));
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final Object... parameters) throws DuplicatedResultException {
return gett(targetClass, sql, StatementSetter.DEFAULT, parameters);
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param sql
* @param statementSetter
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters)
throws DuplicatedResultException {
return gett(targetClass, sql, statementSetter, null, parameters);
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param sql
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters)
throws DuplicatedResultException {
return gett(targetClass, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings,
final Object... parameters) throws DuplicatedResultException {
return gett(targetClass, null, sql, statementSetter, jdbcSettings, parameters);
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final Object... parameters) throws DuplicatedResultException {
return gett(targetClass, conn, sql, StatementSetter.DEFAULT, parameters);
}
/**
* Gets the t.
*
* @param
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param parameters it can be {@code Object[]/List} for (named) parameterized query, or {@code Map/Entity} for named parameterized query.
* DO NOT use primitive array {@code boolean[]/char[]/byte[]/short[]/int[]/long[]/float[]/double[]} for passing multiple parameters.
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) throws DuplicatedResultException {
return gett(targetClass, conn, sql, statementSetter, null, parameters);
}
/**
* Gets the t.
*
* @param