All Downloads are FREE. Search and download functionalities are using the official Maven repository.
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.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
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.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.landawn.abacus.DataSet;
import com.landawn.abacus.DataSource;
import com.landawn.abacus.DataSourceManager;
import com.landawn.abacus.DataSourceSelector;
import com.landawn.abacus.DirtyMarker;
import com.landawn.abacus.IsolationLevel;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.Id;
import com.landawn.abacus.annotation.ReadOnlyId;
import com.landawn.abacus.condition.And;
import com.landawn.abacus.condition.Condition;
import com.landawn.abacus.condition.ConditionFactory.L;
import com.landawn.abacus.condition.Equal;
import com.landawn.abacus.dataSource.SQLDataSource;
import com.landawn.abacus.exception.AbacusException;
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.type.Type;
import com.landawn.abacus.util.Fn.FN;
import com.landawn.abacus.util.Fn.Suppliers;
import com.landawn.abacus.util.JdbcUtil.BiRecordGetter;
import com.landawn.abacus.util.JdbcUtil.PreparedQuery;
import com.landawn.abacus.util.SQLBuilder.NE;
import com.landawn.abacus.util.SQLBuilder.NE2;
import com.landawn.abacus.util.SQLBuilder.NE3;
import com.landawn.abacus.util.SQLBuilder.SP;
import com.landawn.abacus.util.StringUtil.Strings;
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.Function;
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;
/**
* 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 Array/List parameters are supported for parameterized sql with '?'.
* Parameters with format of Array/List/Map/Entity are supported for parameterized SQL with named 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.
*
*
* The general programming way with SQLExeucte is to execute sql scripts(generated by SQLBuilder) with array/list/map/entity by calling (batch)insert/update/delete/query/... methods.
* if Transaction is required. it can be started:
*
*
* final SQLTransaction tran = sqlExecutor.beginTransaction(IsolationLevel.READ_COMMITTED);
boolean noException = false;
try {
// sqlExecutor.insert(...);
// sqlExecutor.update(...);
// sqlExecutor.query(...);
noException = true;
} finally {
// The connection will be automatically closed after the transaction is committed or rolled back.
if (noException) {
tran.commit();
} else {
tran.rollback();
}
}
*
*
*
* SQLExecutor is tread-safe.
*
* @since 0.8
*
* @author Haiyang Li
*
* @see JdbcUtil
*
* @see {@link com.landawn.abacus.annotation.ReadOnly}
* @see {@link com.landawn.abacus.annotation.ReadOnlyId}
* @see {@link com.landawn.abacus.annotation.NonUpdatable}
* @see {@link com.landawn.abacus.annotation.Transient}
* @see {@link com.landawn.abacus.annotation.Table}
* @see {@link com.landawn.abacus.annotation.Column}
*
* @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
*/
public class SQLExecutor implements Closeable {
private static final Logger logger = LoggerFactory.getLogger(SQLExecutor.class);
static final String ID = "id";
static final String QUERY_WITH_DATA_SOURCE = "queryWithDataSource";
private static final ResultExtractor EXISTS_RESULT_SET_EXTRACTOR = new ResultExtractor() {
@Override
public Boolean extractData(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
return rs.next();
}
};
private static final ResultExtractor COUNT_RESULT_SET_EXTRACTOR = new ResultExtractor() {
@Override
public Integer extractData(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
int cnt = 0;
while (rs.next()) {
cnt++;
}
return cnt;
}
};
private static final ResultExtractor SINGLE_BOOLEAN_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalBoolean extractData(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();
}
};
private static final ResultExtractor SINGLE_CHAR_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalChar extractData(final ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
JdbcUtil.skip(rs, jdbcSettings.getOffset());
if (rs.next()) {
final String str = rs.getString(1);
return OptionalChar.of(str == null || str.length() == 0 ? N.CHAR_0 : str.charAt(0));
}
return OptionalChar.empty();
}
};
private static final ResultExtractor SINGLE_BYTE_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalByte extractData(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();
}
};
private static final ResultExtractor SINGLE_SHORT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalShort extractData(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();
}
};
private static final ResultExtractor SINGLE_INT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalInt extractData(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();
}
};
private static final ResultExtractor SINGLE_LONG_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalLong extractData(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();
}
};
private static final ResultExtractor SINGLE_FLOAT_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalFloat extractData(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();
}
};
private static final ResultExtractor SINGLE_DOUBLE_EXTRACTOR = new ResultExtractor() {
@Override
public OptionalDouble extractData(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();
}
};
private static final ResultExtractor> SINGLE_BIG_DECIMAL_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable extractData(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();
}
};
private static final ResultExtractor> SINGLE_STRING_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable extractData(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();
}
};
private static final ResultExtractor> SINGLE_DATE_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable extractData(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();
}
};
private static final ResultExtractor> SINGLE_TIME_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable extractData(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();
}
};
private static final ResultExtractor> SINGLE_TIMESTAMP_EXTRACTOR = new ResultExtractor>() {
@Override
public Nullable extractData(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();
}
};
private static final ResultExtractor RESULT_SET_EXTRACTOR = new ResultExtractor() {
@Override
public ResultSet extractData(ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
return rs;
}
};
private static final int factor = Math.min(Math.max(1, IOUtil.MAX_MEMORY_IN_MB / 1024), 8);
private static final int CACHED_SQL_LENGTH = 1024 * factor;
private static final int SQL_CACHE_SIZE = 1000 * factor;
private static final Map> _sqlColumnLabelPool = new ConcurrentHashMap<>();
private final Map> _tableColumnNamePool = new ConcurrentHashMap<>();
private final DataSource _ds;
private final DataSourceManager _dsm;
private final DataSourceSelector _dss;
private final JdbcSettings _jdbcSettings;
private final SQLMapper _sqlMapper;
private final NamingPolicy _namingPolicy;
private final AsyncExecutor _asyncExecutor;
private final boolean _isReadOnly;
private final String _dbProudctName;
private final String _dbProudctVersion;
private final DBVersion _dbVersion;
private final IsolationLevel _defaultIsolationLevel;
private final AsyncSQLExecutor _asyncSQLExecutor;
private final Map, Mapper>> mapperPool = new ConcurrentHashMap<>();
/**
*
* @param dataSource
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final javax.sql.DataSource dataSource) {
this(dataSource, null);
}
/**
*
* @param dataSource
* @param jdbcSettings
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final javax.sql.DataSource dataSource, final JdbcSettings jdbcSettings) {
this(dataSource, jdbcSettings, null);
}
/**
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final javax.sql.DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper) {
this(dataSource, jdbcSettings, sqlMapper, null);
}
/**
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @param namingPolicy
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final javax.sql.DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy) {
this(dataSource, jdbcSettings, sqlMapper, namingPolicy, null);
}
/**
*
* @param dataSource
* @param jdbcSettings
* @param sqlMapper
* @param asyncExecutor
* @see JdbcUtil#createDataSource(String)
* @see JdbcUtil#createDataSource(java.io.InputStream)
*/
public SQLExecutor(final javax.sql.DataSource dataSource, final JdbcSettings jdbcSettings, final SQLMapper sqlMapper, final NamingPolicy namingPolicy,
final AsyncExecutor asyncExecutor) {
this(null, JdbcUtil.wrap(dataSource), jdbcSettings, sqlMapper, namingPolicy, asyncExecutor, false);
}
/**
*
* @param dataSourceManager
* @see JdbcUtil#createDataSourceManager(String)
* @see JdbcUtil#createDataSourceManager(java.io.InputStream)
*/
public SQLExecutor(final DataSourceManager dataSourceManager) {
this(dataSourceManager, null);
}
/**
*
* @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);
}
/**
*
* @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);
}
/**
*
* @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);
}
/**
*
* @param dataSourceManager
* @param jdbcSettings
* @param sqlMapper
* @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);
}
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(64, 300, 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 {
closeQuietly(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 javax.sql.DataSource sqlDataSource) {
// return new SQLExecutor(JdbcUtil.wrap(sqlDataSource));
// }
//
// public SQLMapper sqlMapper() {
// return _sqlMapper;
// }
@Beta
public static SQLExecutor w(final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(url, user, password));
}
@Beta
public static SQLExecutor w(final String driver, final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(driver, url, user, password));
}
@Beta
public static SQLExecutor w(final Class extends Driver> driverClass, final String url, final String user, final String password) {
return new SQLExecutor(JdbcUtil.createDataSource(driverClass, url, user, password));
}
public Mapper mapper(final Class targetClass) {
Mapper mapper = (Mapper) mapperPool.get(targetClass);
if (mapper == null) {
N.checkArgument(N.isEntity(targetClass), ClassUtil.getCanonicalClassName(targetClass) + " is not an entity class with getter/setter methods");
SQLBuilder.registerEntityPropColumnNameMap(targetClass);
mapper = new Mapper(targetClass, this, this._namingPolicy);
mapperPool.put(targetClass, mapper);
}
return mapper;
}
// /**
// * Create a Mapper
which has the same life cycle as the specified Connection
.
// * To start transaction for a Mapper
:
// *
// *
// * final Transaction tran = sqlExecutor.beginTransaction(isolationLevel);
// * final ExMapper mapper = sqlExecutor.mapper(targetClass, tran.connection());
// * boolean isOk = false;
// * try {
// * // Do something with sqlExecutor and mapper
// * isOk = true;
// * } finally {
// * if (isOk) {
// * tran.commit();
// * } else {
// * tran.rollback();
// * }
// * }
// *
// *
// *
// * @param targetClass
// * @param conn
// * @return
// */
// public ExMapper mapper(final Class targetClass, final Connection conn) {
// if (conn == null) {
// return mapper(targetClass);
// }
//
// return new ExMapper(conn, targetClass, this, this._namingPolicy);
// }
public AsyncSQLExecutor async() {
return _asyncSQLExecutor;
}
public DataSource dataSource() {
return _ds;
}
public JdbcSettings jdbcSettings() {
return _jdbcSettings;
}
public String dbProudctName() {
return _dbProudctName;
}
public String dbProudctVersion() {
return _dbProudctVersion;
}
public DBVersion dbVersion() {
return _dbVersion;
}
@SafeVarargs
public final T insert(final String sql, final Object... parameters) throws UncheckedSQLException {
return insert(sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final T insert(final String sql, final StatementSetter statementSetter, final Object... parameters) throws UncheckedSQLException {
return insert(sql, statementSetter, null, parameters);
}
@SafeVarargs
public final T insert(final String sql, final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return insert(sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
@SafeVarargs
public final T insert(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return insert(null, sql, statementSetter, jdbcSettings, parameters);
}
@SafeVarargs
public final T insert(final Connection conn, final String sql, final Object... parameters) throws UncheckedSQLException {
return insert(conn, sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final T insert(final Connection conn, final String sql, final StatementSetter statementSetter, final Object... parameters)
throws UncheckedSQLException {
return insert(conn, sql, statementSetter, null, parameters);
}
public final T insert(final Connection conn, final String sql, final JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
return insert(conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
* @see #batchInsert(Connection, String, StatementSetter, JdbcSettings, String, Object[])
*/
@SuppressWarnings({ "unchecked", "deprecation" })
@SafeVarargs
public final T insert(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings, final Object... parameters)
throws UncheckedSQLException {
final NamedSQL namedSQL = getNamedSQL(sql);
statementSetter = checkStatementSetter(namedSQL, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, namedSQL, _sqlMapper.getAttrs(sql));
String idPropName = checkGeneratedIdPropName(jdbcSettings);
DataSource ds = null;
Connection localConn = null;
Object result = null;
PreparedStatement stmt = null;
try {
ds = getDataSource(namedSQL.getPureSQL(), parameters, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.INSERT);
stmt = prepareStatement(ds, localConn, namedSQL, statementSetter, jdbcSettings, true, false, parameters);
result = executeInsert(namedSQL, stmt);
} catch (SQLException e) {
String msg = AbacusException.getErrorMsg(e) + ". [SQL] " + namedSQL.getNamedSQL();
logger.error(msg);
throw new UncheckedSQLException(msg, e);
} finally {
closeQuietly(stmt);
closeQuietly(localConn, conn, ds);
}
if ((result != null) && isEntityOrMapParameter(namedSQL, parameters)) {
Object parameter_0 = parameters[0];
if (parameter_0 instanceof Map) {
// // don't update input map ?
// Map m = (Map) parameter_0;
// Object idPropValue = m.get(generatedIdPropName);
//
// if ((idPropValue == null)
// || (idPropValue instanceof Number
// && (((Number) idPropValue).longValue() == 0))) {
// m.put(generatedIdPropName, result);
// }
} else {
final Object entity = parameter_0;
try {
Method idGetMethod = ClassUtil.getPropGetMethod(entity.getClass(), idPropName);
Method idSetMethod = ClassUtil.getPropSetMethod(entity.getClass(), idPropName);
if ((idGetMethod != null) && (idSetMethod != null)) {
Object idPropValue = ClassUtil.getPropValue(entity, idGetMethod);
if ((idPropValue == null) || (idPropValue instanceof Number && (((Number) idPropValue).longValue() == 0))) {
ClassUtil.setPropValue(entity, idSetMethod, result);
}
} else {
if (logger.isWarnEnabled()) {
logger.warn("Failed to set the returned id property to entity. no get/set method for id property (" + idPropName + ") found. ");
}
}
} catch (Exception e) {
logger.error("Failed to set the returned id property to entity", e);
}
if (entity instanceof DirtyMarker) {
((DirtyMarker) entity).dirtyPropNames().clear();
}
}
}
return (T) result;
}
protected Object executeInsert(final NamedSQL namedSQL, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new AbacusException("This SQL Executor is configured for read-only");
}
stmt.executeUpdate();
Object id = null;
ResultSet rs = null;
try {
rs = stmt.getGeneratedKeys();
if (rs.next()) {
id = JdbcUtil.getColumnValue(rs, 1);
}
} catch (SQLException e) {
logger.error("Failed to retrieve the auto-generated Ids", e);
} finally {
closeQuietly(rs);
}
return id;
}
public List batchInsert(final String sql, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, StatementSetter.DEFAULT, parametersList);
}
public List batchInsert(final String sql, final StatementSetter statementSetter, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, statementSetter, null, parametersList);
}
public List batchInsert(final String sql, final JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
return batchInsert(sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
public List batchInsert(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchInsert(null, sql, statementSetter, jdbcSettings, parametersList);
}
public List batchInsert(final Connection conn, final String sql, final List> parametersList) throws UncheckedSQLException {
return batchInsert(conn, sql, StatementSetter.DEFAULT, parametersList);
}
public List batchInsert(final Connection conn, final String sql, final StatementSetter statementSetter, final List> parametersList)
throws UncheckedSQLException {
return batchInsert(conn, sql, statementSetter, null, parametersList);
}
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);
}
/**
*
* @see #batchInsert(Connection, String, StatementSetter, JdbcSettings, Object[])
*/
@SuppressWarnings("deprecation")
public List batchInsert(final Connection conn, final String sql, StatementSetter statementSetter, JdbcSettings jdbcSettings,
final List> parametersList) throws UncheckedSQLException {
final NamedSQL namedSQL = getNamedSQL(sql);
statementSetter = checkStatementSetter(namedSQL, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, namedSQL, _sqlMapper.getAttrs(sql));
String idPropName = checkGeneratedIdPropName(jdbcSettings);
final int len = parametersList.size();
final int batchSize = getBatchSize(jdbcSettings);
List resultIdList = new ArrayList<>(len);
DataSource ds = null;
Connection localConn = null;
PreparedStatement stmt = null;
int originalIsolationLevel = 0;
boolean autoCommit = true;
try {
ds = getDataSource(namedSQL.getPureSQL(), parametersList, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.INSERT);
try {
originalIsolationLevel = localConn.getTransactionIsolation();
autoCommit = localConn.getAutoCommit();
} catch (SQLException e) {
closeQuietly(localConn, conn, ds);
throw new UncheckedSQLException(e);
}
if ((conn == null) && (len > batchSize)) {
localConn.setAutoCommit(false);
setIsolationLevel(jdbcSettings, localConn);
}
stmt = prepareStatement(ds, localConn, namedSQL, statementSetter, jdbcSettings, true, true, parametersList);
if (len <= batchSize) {
for (int i = 0; i < len; i++) {
statementSetter.setParameters(namedSQL, stmt, N.asArray(parametersList.get(i)));
stmt.addBatch();
}
executeBatchInsert(resultIdList, namedSQL, stmt);
} else {
int num = 0;
for (int i = 0; i < len; i++) {
statementSetter.setParameters(namedSQL, stmt, N.asArray(parametersList.get(i)));
stmt.addBatch();
num++;
if ((num % batchSize) == 0) {
executeBatchInsert(resultIdList, namedSQL, stmt);
}
}
if ((num % batchSize) > 0) {
executeBatchInsert(resultIdList, namedSQL, stmt);
}
}
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 = AbacusException.getErrorMsg(e) + ". [SQL] " + namedSQL.getNamedSQL();
logger.error(msg);
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);
}
}
closeQuietly(stmt);
closeQuietly(localConn, conn, ds);
}
if (N.notNullOrEmpty(resultIdList)) {
if (isEntityOrMapParameter(namedSQL, parametersList.get(0))) {
if (resultIdList.size() == len) {
Object parameter_0 = parametersList.get(0);
if (parameter_0 instanceof Map) {
// // don't update input map ?
// Map m = null;
// Object idPropValue = null;
//
// for (int i = 0; i < parameters.length; i++) {
// m = (Map) (isTypedParameter
// ? ((TypedParameters) parameters[i]).parameters[0] :
// parameters[i]);
// idPropValue = m.get(generatedIdPropName);
//
// if ((idPropValue == null)
// || (idPropValue instanceof Number
// && (((Number) idPropValue).longValue() == 0))) {
// m.put(generatedIdPropName, resultList.get(i));
// }
// }
} else {
try {
Method idGetMethod = ClassUtil.getPropGetMethod(parameter_0.getClass(), idPropName);
Method idSetMethod = ClassUtil.getPropSetMethod(parameter_0.getClass(), idPropName);
if ((idGetMethod != null) && (idSetMethod != null)) {
Object entity = null;
Object idPropValue = null;
for (int i = 0; i < len; i++) {
entity = parametersList.get(i);
idPropValue = ClassUtil.invokeMethod(entity, idGetMethod);
if ((idPropValue == null) || (idPropValue instanceof Number && (((Number) idPropValue).longValue() == 0))) {
ClassUtil.setPropValue(entity, idSetMethod, resultIdList.get(i));
}
if (entity instanceof DirtyMarker) {
((DirtyMarker) entity).dirtyPropNames().clear();
}
}
} else {
if (logger.isWarnEnabled()) {
logger.warn(
"Failed to set the returned id property to entity. no get/set method for id property (" + idPropName + ") found. ");
}
}
} catch (Exception e) {
logger.error("Failed to set the returned id property to entity", e);
}
}
} 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");
}
}
}
}
return resultIdList;
}
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);
}
}
protected void executeBatchInsert(final List resultIdList, final NamedSQL namedSQL, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new AbacusException("This SQL Executor is configured for read-only");
}
stmt.executeBatch();
ResultSet rs = null;
try {
rs = stmt.getGeneratedKeys();
while (rs.next()) {
resultIdList.add((T) JdbcUtil.getColumnValue(rs, 1));
}
} catch (SQLException e) {
logger.error("Failed to retrieve the auto-generated Ids", e);
} finally {
closeQuietly(rs);
}
stmt.clearBatch();
}
@SafeVarargs
public final int update(final String sql, final Object... parameters) throws UncheckedSQLException {
return update(sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final int update(final String sql, final StatementSetter statementSetter, final Object... parameters) throws UncheckedSQLException {
return update(sql, statementSetter, null, parameters);
}
@SafeVarargs
public final int update(final String sql, final JdbcSettings jdbcSettings, final Object... parameters) throws UncheckedSQLException {
return update(sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
@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);
}
@SafeVarargs
public final int update(final Connection conn, final String sql, final Object... parameters) throws UncheckedSQLException {
return update(conn, sql, StatementSetter.DEFAULT, parameters);
}
@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);
}
@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);
}
/**
* @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 NamedSQL namedSQL = getNamedSQL(sql);
statementSetter = checkStatementSetter(namedSQL, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, namedSQL, _sqlMapper.getAttrs(sql));
DataSource ds = null;
Connection localConn = null;
PreparedStatement stmt = null;
try {
ds = getDataSource(namedSQL.getPureSQL(), parameters, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.UPDATE);
stmt = prepareStatement(ds, localConn, namedSQL, statementSetter, jdbcSettings, false, false, parameters);
return executeUpdate(namedSQL, stmt);
} catch (SQLException e) {
String msg = AbacusException.getErrorMsg(e) + ". [SQL] " + namedSQL.getNamedSQL();
logger.error(msg);
throw new UncheckedSQLException(msg, e);
} finally {
closeQuietly(stmt);
closeQuietly(localConn, conn, ds);
}
}
protected int executeUpdate(final NamedSQL namedSQL, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new AbacusException("This SQL Executor is configured for read-only");
}
return stmt.executeUpdate();
}
public int batchUpdate(final String sql, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, StatementSetter.DEFAULT, parametersList);
}
public int batchUpdate(final String sql, final StatementSetter statementSetter, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, statementSetter, null, parametersList);
}
public int batchUpdate(final String sql, final JdbcSettings jdbcSettings, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(sql, StatementSetter.DEFAULT, jdbcSettings, parametersList);
}
public int batchUpdate(final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings, final List> parametersList)
throws UncheckedSQLException {
return batchUpdate(null, sql, statementSetter, jdbcSettings, parametersList);
}
public int batchUpdate(final Connection conn, final String sql, final List> parametersList) throws UncheckedSQLException {
return batchUpdate(conn, sql, StatementSetter.DEFAULT, parametersList);
}
public int batchUpdate(final Connection conn, final String sql, final StatementSetter statementSetter, final List> parametersList)
throws UncheckedSQLException {
return batchUpdate(conn, sql, statementSetter, null, parametersList);
}
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);
}
/**
* @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 NamedSQL namedSQL = getNamedSQL(sql);
statementSetter = checkStatementSetter(namedSQL, statementSetter);
jdbcSettings = checkJdbcSettings(jdbcSettings, namedSQL, _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(namedSQL.getPureSQL(), parametersList, jdbcSettings);
localConn = getConnection(conn, ds, jdbcSettings, SQLOperation.UPDATE);
try {
originalIsolationLevel = localConn.getTransactionIsolation();
autoCommit = localConn.getAutoCommit();
} catch (SQLException e) {
closeQuietly(localConn, conn, ds);
throw new UncheckedSQLException(e);
}
if ((conn == null) && (len > batchSize)) {
localConn.setAutoCommit(false);
setIsolationLevel(jdbcSettings, localConn);
}
stmt = prepareStatement(ds, localConn, namedSQL, statementSetter, jdbcSettings, false, true, parametersList);
int result = 0;
if (len <= batchSize) {
for (int i = 0; i < len; i++) {
statementSetter.setParameters(namedSQL, stmt, N.asArray(parametersList.get(i)));
stmt.addBatch();
}
result += executeBatchUpdate(namedSQL, stmt);
} else {
int num = 0;
for (int i = 0; i < len; i++) {
statementSetter.setParameters(namedSQL, stmt, N.asArray(parametersList.get(i)));
stmt.addBatch();
num++;
if ((num % batchSize) == 0) {
result += executeBatchUpdate(namedSQL, stmt);
}
}
if ((num % batchSize) > 0) {
result += executeBatchUpdate(namedSQL, stmt);
}
}
if ((conn == null) && (len > batchSize) && autoCommit == true) {
localConn.commit();
}
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 = AbacusException.getErrorMsg(e) + ". [SQL] " + namedSQL.getNamedSQL();
logger.error(msg);
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);
}
}
closeQuietly(stmt);
closeQuietly(localConn, conn, ds);
}
}
protected int executeBatchUpdate(final NamedSQL namedSQL, final PreparedStatement stmt) throws SQLException {
if (_isReadOnly) {
throw new AbacusException("This SQL Executor is configured for read-only");
}
final int[] results = stmt.executeBatch();
stmt.clearBatch();
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, pair.sql, pair.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, pair.sql, pair.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, pair.sql, StatementSetter.DEFAULT, EXISTS_RESULT_SET_EXTRACTOR, null, pair.parameters);
// }
@SafeVarargs
public final boolean exists(final String sql, final Object... parameters) {
return exists(null, sql, parameters);
}
@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);
}
@SafeVarargs
public final int count(final String sql, final Object... parameters) {
return count(null, sql, parameters);
}
@SafeVarargs
public 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 targetClass
* @param sql
* @param 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) {
return Optional.ofNullable(gett(targetClass, sql, parameters));
}
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters) {
return Optional.ofNullable(gett(targetClass, sql, statementSetter, parameters));
}
@SafeVarargs
public final Optional get(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) {
return Optional.ofNullable(gett(targetClass, sql, jdbcSettings, parameters));
}
/**
*
* @param targetClass
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param 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) {
return Optional.ofNullable(gett(targetClass, sql, statementSetter, jdbcSettings, parameters));
}
/**
*
* @param targetClass
* @param conn
* @param sql
* @param 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) {
return Optional.ofNullable(gett(targetClass, conn, sql, parameters));
}
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) {
return Optional.ofNullable(gett(targetClass, conn, sql, statementSetter, parameters));
}
@SafeVarargs
public final Optional get(final Class targetClass, final Connection conn, final String sql, final JdbcSettings jdbcSettings,
final Object... parameters) {
return Optional.ofNullable(gett(targetClass, conn, sql, jdbcSettings, parameters));
}
/**
*
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param 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) {
return Optional.ofNullable(gett(targetClass, conn, sql, statementSetter, jdbcSettings, parameters));
}
/**
* v
* @param sql
* @param recordGetter
* @param parameters
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final String sql, final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return Optional.ofNullable(gett(sql, recordGetter, parameters));
}
public final Optional get(final String sql, final StatementSetter statementSetter, final JdbcUtil.RecordGetter recordGetter,
final Object... parameters) {
return Optional.ofNullable(gett(sql, statementSetter, recordGetter, parameters));
}
public final Optional get(final String sql, final JdbcUtil.RecordGetter recordGetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return Optional.ofNullable(gett(sql, recordGetter, jdbcSettings, parameters));
}
/**
*
* @param sql
* @param statementSetter
* @param recordGetter
* @param jdbcSettings
* @param parameters
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final String sql, final StatementSetter statementSetter, final JdbcUtil.RecordGetter recordGetter,
final JdbcSettings jdbcSettings, final Object... parameters) {
return Optional.ofNullable(gett(sql, statementSetter, recordGetter, jdbcSettings, parameters));
}
/**
*
* @param conn
* @param sql
* @param recordGetter
* @param parameters
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter,
final Object... parameters) {
return Optional.ofNullable(gett(conn, sql, recordGetter, parameters));
}
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return Optional.ofNullable(gett(conn, sql, statementSetter, recordGetter, parameters));
}
@SafeVarargs
public final Optional get(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter,
JdbcSettings jdbcSettings, final Object... parameters) {
return Optional.ofNullable(gett(conn, sql, recordGetter, jdbcSettings, parameters));
}
/**
*
* @param conn
* @param sql
* @param statementSetter
* @param recordGetter
* @param jdbcSettings
* @param 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.RecordGetter recordGetter, final JdbcSettings jdbcSettings, final Object... parameters) {
return Optional.ofNullable(gett(conn, sql, statementSetter, recordGetter, jdbcSettings, parameters));
}
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final Object... parameters) {
return gett(targetClass, sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters) {
return gett(targetClass, sql, statementSetter, null, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) {
return gett(targetClass, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return gett(targetClass, null, sql, statementSetter, jdbcSettings, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final Object... parameters) {
return gett(targetClass, conn, sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) {
return gett(targetClass, conn, sql, statementSetter, null, parameters);
}
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) {
return gett(targetClass, conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public final T gett(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
JdbcSettings jdbcSettings, final Object... parameters) {
N.checkArgNotNull(targetClass, "targetClass");
final JdbcUtil.RecordGetter recordGetter = new JdbcUtil.RecordGetter() {
private final BiRecordGetter biRecordGetter = BiRecordGetter.to(targetClass);
@Override
public T apply(ResultSet rs) throws SQLException {
return biRecordGetter.apply(rs, JdbcUtil.getColumnLabelList(rs));
}
};
return gett(conn, sql, statementSetter, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final T gett(final String sql, final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return gett(sql, StatementSetter.DEFAULT, recordGetter, parameters);
}
@SafeVarargs
public final T gett(final String sql, final StatementSetter statementSetter, final JdbcUtil.RecordGetter recordGetter,
final Object... parameters) {
return gett(sql, statementSetter, recordGetter, null, parameters);
}
@SafeVarargs
public final T gett(final String sql, final JdbcUtil.RecordGetter recordGetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return gett(sql, StatementSetter.DEFAULT, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final T gett(final String sql, final StatementSetter statementSetter, final JdbcUtil.RecordGetter recordGetter,
final JdbcSettings jdbcSettings, final Object... parameters) {
return gett(null, sql, statementSetter, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final T gett(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter,
final Object... parameters) {
return gett(conn, sql, StatementSetter.DEFAULT, recordGetter, parameters);
}
public final T gett(final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return gett(conn, sql, statementSetter, recordGetter, null, parameters);
}
public final T gett(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter, JdbcSettings jdbcSettings,
final Object... parameters) {
return gett(conn, sql, StatementSetter.DEFAULT, recordGetter, jdbcSettings, parameters);
}
/**
*v
* @param conn
* @param sql
* @param statementSetter
* @param recordGetter
* @param jdbcSettings
* @param parameters
* @return
* @throws DuplicatedResultException if two or more records are found.
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public final T gett(final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, JdbcSettings jdbcSettings, final Object... parameters) {
N.checkArgNotNull(recordGetter, "recordGetter");
final ResultExtractor resultExtractor = new ResultExtractor() {
@Override
public T extractData(ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
int offset = jdbcSettings.getOffset();
if (offset > 0) {
JdbcUtil.skip(rs, offset);
}
T result = null;
if (rs.next()) {
result = Objects.requireNonNull(recordGetter.apply(rs));
if (rs.next()) {
throw new DuplicatedResultException("More than one records found by sql: " + sql);
}
}
return result;
}
};
return query(conn, sql, statementSetter, resultExtractor, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final Class targetClass, final String sql, final Object... parameters) {
return findFirst(targetClass, sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final Optional findFirst(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters) {
return findFirst(targetClass, sql, statementSetter, null, parameters);
}
@SafeVarargs
public final Optional findFirst(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) {
return findFirst(targetClass, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final Class targetClass, final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return findFirst(targetClass, null, sql, statementSetter, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final Class targetClass, final Connection conn, final String sql, final Object... parameters) {
return findFirst(targetClass, conn, sql, StatementSetter.DEFAULT, parameters);
}
public final Optional findFirst(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) {
return findFirst(targetClass, conn, sql, statementSetter, null, parameters);
}
public final Optional findFirst(final Class targetClass, final Connection conn, final String sql, final JdbcSettings jdbcSettings,
final Object... parameters) {
return findFirst(targetClass, conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
* Just fetch the result in the 1st row. {@code null} is returned if no result is found. This method will try to
* convert the column value to the type of mapping entity property if the mapping entity property is not assignable
* from column value.
*
* Remember to add {@code limit} condition if big result will be returned by the query.
*
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public final Optional findFirst(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcSettings jdbcSettings, final Object... parameters) {
N.checkArgNotNull(targetClass, "targetClass");
final JdbcUtil.RecordGetter recordGetter = new JdbcUtil.RecordGetter() {
private final BiRecordGetter biRecordGetter = BiRecordGetter.to(targetClass);
@Override
public T apply(ResultSet rs) throws SQLException {
return biRecordGetter.apply(rs, JdbcUtil.getColumnLabelList(rs));
}
};
return findFirst(conn, sql, statementSetter, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final String sql, final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return findFirst(sql, StatementSetter.DEFAULT, recordGetter, parameters);
}
@SafeVarargs
public final Optional findFirst(final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return findFirst(sql, statementSetter, recordGetter, null, parameters);
}
@SafeVarargs
public final Optional findFirst(final String sql, final JdbcUtil.RecordGetter recordGetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return findFirst(sql, StatementSetter.DEFAULT, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final JdbcSettings jdbcSettings, final Object... parameters) {
return findFirst(null, sql, statementSetter, recordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final Optional findFirst(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter,
final Object... parameters) {
return findFirst(conn, sql, StatementSetter.DEFAULT, recordGetter, parameters);
}
public final Optional findFirst(final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final Object... parameters) {
return findFirst(conn, sql, statementSetter, recordGetter, null, parameters);
}
public final Optional findFirst(final Connection conn, final String sql, final JdbcUtil.RecordGetter recordGetter,
final JdbcSettings jdbcSettings, final Object... parameters) {
return findFirst(conn, sql, StatementSetter.DEFAULT, recordGetter, jdbcSettings, parameters);
}
/**
*
* Remember to add {@code limit} condition if big result will be returned by the query.
*
* @param conn
* @param sql
* @param statementSetter
* @param recordGetter
* @param jdbcSettings
* @param parameters
* @return
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public final Optional findFirst(final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcUtil.RecordGetter recordGetter, final JdbcSettings jdbcSettings, final Object... parameters) {
N.checkArgNotNull(recordGetter, "recordGetter");
final ResultExtractor resultExtractor = new ResultExtractor() {
@Override
public T extractData(ResultSet rs, final JdbcSettings jdbcSettings) throws SQLException {
int offset = jdbcSettings.getOffset();
if (offset > 0) {
JdbcUtil.skip(rs, offset);
}
return rs.next() ? Objects.requireNonNull(recordGetter.apply(rs)) : null;
}
};
return Optional.ofNullable(query(conn, sql, statementSetter, resultExtractor, jdbcSettings, parameters));
}
@SafeVarargs
public final List list(final Class targetClass, final String sql, final Object... parameters) {
return list(targetClass, sql, StatementSetter.DEFAULT, parameters);
}
@SafeVarargs
public final List list(final Class targetClass, final String sql, final StatementSetter statementSetter, final Object... parameters) {
return list(targetClass, sql, statementSetter, null, parameters);
}
@SafeVarargs
public final List list(final Class targetClass, final String sql, final JdbcSettings jdbcSettings, final Object... parameters) {
return list(targetClass, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
@SafeVarargs
public final List list(final Class targetClass, final String sql, final StatementSetter statementSetter, final JdbcSettings jdbcSettings,
final Object... parameters) {
return list(targetClass, null, sql, statementSetter, jdbcSettings, parameters);
}
@SafeVarargs
public final List list(final Class targetClass, final Connection conn, final String sql, final Object... parameters) {
return list(targetClass, conn, sql, StatementSetter.DEFAULT, parameters);
}
public final List list(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final Object... parameters) {
return list(targetClass, conn, sql, statementSetter, null, parameters);
}
public final List list(final Class targetClass, final Connection conn, final String sql, final JdbcSettings jdbcSettings,
final Object... parameters) {
return list(targetClass, conn, sql, StatementSetter.DEFAULT, jdbcSettings, parameters);
}
/**
*
* @param targetClass
* @param conn
* @param sql
* @param statementSetter
* @param jdbcSettings
* @param parameters
* @return
*/
@SuppressWarnings("unchecked")
@SafeVarargs
public final List list(final Class targetClass, final Connection conn, final String sql, final StatementSetter statementSetter,
final JdbcSettings jdbcSettings, final Object... parameters) {
final JdbcUtil.BiRecordGetter biRecordGetter = BiRecordGetter.to(targetClass);
return list(conn, sql, statementSetter, biRecordGetter, jdbcSettings, parameters);
}
@SafeVarargs
public final List list(final String sql, final JdbcUtil.BiRecordGetter recordGetter, final Object... parameters) {
return list(sql, StatementSetter.DEFAULT, recordGetter, parameters);
}
@SafeVarargs
public final List