com.landawn.abacus.util.JdbcUtil 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 static com.landawn.abacus.dataSource.DataSourceConfiguration.DRIVER; import static com.landawn.abacus.dataSource.DataSourceConfiguration.PASSWORD; import static com.landawn.abacus.dataSource.DataSourceConfiguration.URL; import static com.landawn.abacus.dataSource.DataSourceConfiguration.USER; import static com.landawn.abacus.util.IOUtil.DEFAULT_QUEUE_SIZE_FOR_ROW_PARSER; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.math.BigDecimal; import java.net.URL; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.Date; import java.sql.Driver; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLType; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import com.landawn.abacus.DataSet; import com.landawn.abacus.DataSource; import com.landawn.abacus.DataSourceManager; 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.annotation.Internal; import com.landawn.abacus.condition.Condition; import com.landawn.abacus.condition.ConditionFactory.CF; import com.landawn.abacus.core.DirtyMarkerUtil; import com.landawn.abacus.core.RowDataSet; import com.landawn.abacus.core.Seid; import com.landawn.abacus.dataSource.DataSourceConfiguration; import com.landawn.abacus.dataSource.DataSourceManagerConfiguration; import com.landawn.abacus.dataSource.SQLDataSource; import com.landawn.abacus.dataSource.SQLDataSourceManager; import com.landawn.abacus.exception.AbacusException; import com.landawn.abacus.exception.DuplicatedResultException; import com.landawn.abacus.exception.ParseException; import com.landawn.abacus.exception.UncheckedIOException; 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.ExceptionalStream.ExceptionalIterator; import com.landawn.abacus.util.ExceptionalStream.StreamE; import com.landawn.abacus.util.Fn.BiConsumers; import com.landawn.abacus.util.Fn.Fnn; import com.landawn.abacus.util.Fn.IntFunctions; import com.landawn.abacus.util.Fn.Suppliers; 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.SQLExecutor.StatementSetter; import com.landawn.abacus.util.SQLTransaction.CreatedBy; import com.landawn.abacus.util.StringUtil.Strings; import com.landawn.abacus.util.Try.Consumer; import com.landawn.abacus.util.Tuple.Tuple2; import com.landawn.abacus.util.Tuple.Tuple3; import com.landawn.abacus.util.Tuple.Tuple4; import com.landawn.abacus.util.Tuple.Tuple5; 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.Function; import com.landawn.abacus.util.function.LongFunction; 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.EntryStream; import com.landawn.abacus.util.stream.IntStream.IntStreamEx; import com.landawn.abacus.util.stream.Stream; import com.landawn.abacus.util.stream.Stream.StreamEx; // TODO: Auto-generated Javadoc /** * The Class JdbcUtil. * * @author Haiyang Li * @see {@link com.landawn.abacus.condition.ConditionFactory} * @see {@link com.landawn.abacus.condition.ConditionFactory.CF} * @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 * @since 0.8 */ public final class JdbcUtil { /** The Constant logger. */ private static final Logger logger = LoggerFactory.getLogger(JdbcUtil.class); /** The Constant DEFAULT_BATCH_SIZE. */ public static final int DEFAULT_BATCH_SIZE = 200; /** The Constant CURRENT_DIR_PATH. */ // ... static final String CURRENT_DIR_PATH = "./"; /** The async executor. */ static final AsyncExecutor asyncExecutor = new AsyncExecutor(Math.max(8, IOUtil.CPU_CORES), Math.max(64, IOUtil.CPU_CORES), 180L, TimeUnit.SECONDS); /** The Constant DEFAULT_STMT_SETTER. */ static final JdbcUtil.BiParametersSetter super PreparedStatement, ? super Object[]> DEFAULT_STMT_SETTER = new JdbcUtil.BiParametersSetter
* * It's incorrect to use flag to identity the transaction should be committed or rolled back. * Don't write below code: *() { @Override public void accept(PreparedStatement stmt, Object[] parameters) throws SQLException { for (int i = 0, len = parameters.length; i < len; i++) { stmt.setObject(i + 1, parameters[i]); } } }; /** The Constant sqlStateForTableNotExists. */ private static final Set sqlStateForTableNotExists = N.newHashSet(); static { sqlStateForTableNotExists.add("42S02"); // for MySQCF. sqlStateForTableNotExists.add("42P01"); // for PostgreSQCF. sqlStateForTableNotExists.add("42501"); // for HSQLDB. } /** * Instantiates a new jdbc util. */ private JdbcUtil() { // singleton } /** * Gets the DB version. * * @param conn * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static DBVersion getDBVersion(final Connection conn) throws UncheckedSQLException { try { String dbProudctName = conn.getMetaData().getDatabaseProductName(); String dbProudctVersion = conn.getMetaData().getDatabaseProductVersion(); DBVersion dbVersion = DBVersion.OTHERS; String upperCaseProductName = dbProudctName.toUpperCase(); if (upperCaseProductName.contains("H2")) { dbVersion = DBVersion.H2; } else if (upperCaseProductName.contains("HSQL")) { dbVersion = DBVersion.HSQLDB; } else if (upperCaseProductName.contains("MYSQL")) { if (dbProudctVersion.startsWith("5.5")) { dbVersion = DBVersion.MYSQL_5_5; } else if (dbProudctVersion.startsWith("5.6")) { dbVersion = DBVersion.MYSQL_5_6; } else if (dbProudctVersion.startsWith("5.7")) { dbVersion = DBVersion.MYSQL_5_7; } else if (dbProudctVersion.startsWith("5.8")) { dbVersion = DBVersion.MYSQL_5_8; } else if (dbProudctVersion.startsWith("5.9")) { dbVersion = DBVersion.MYSQL_5_9; } else if (dbProudctVersion.startsWith("6")) { dbVersion = DBVersion.MYSQL_6; } else if (dbProudctVersion.startsWith("7")) { dbVersion = DBVersion.MYSQL_7; } else if (dbProudctVersion.startsWith("8")) { dbVersion = DBVersion.MYSQL_8; } else if (dbProudctVersion.startsWith("9")) { dbVersion = DBVersion.MYSQL_9; } else if (dbProudctVersion.startsWith("10")) { dbVersion = DBVersion.MYSQL_10; } else { dbVersion = DBVersion.MYSQL_OTHERS; } } else if (upperCaseProductName.contains("POSTGRESQL")) { if (dbProudctVersion.startsWith("9.2")) { dbVersion = DBVersion.POSTGRESQL_9_2; } else if (dbProudctVersion.startsWith("9.3")) { dbVersion = DBVersion.POSTGRESQL_9_3; } else if (dbProudctVersion.startsWith("9.4")) { dbVersion = DBVersion.POSTGRESQL_9_4; } else if (dbProudctVersion.startsWith("9.5")) { dbVersion = DBVersion.POSTGRESQL_9_5; } else if (dbProudctVersion.startsWith("10")) { dbVersion = DBVersion.POSTGRESQL_10; } else if (dbProudctVersion.startsWith("11")) { dbVersion = DBVersion.POSTGRESQL_11; } else if (dbProudctVersion.startsWith("12")) { dbVersion = DBVersion.POSTGRESQL_12; } else { dbVersion = DBVersion.POSTGRESQL_OTHERS; } } else if (upperCaseProductName.contains("ORACLE")) { dbVersion = DBVersion.ORACLE; } else if (upperCaseProductName.contains("DB2")) { dbVersion = DBVersion.DB2; } else if (upperCaseProductName.contains("SQL SERVER")) { dbVersion = DBVersion.SQL_SERVER; } return dbVersion; } catch (SQLException e) { throw new UncheckedSQLException(e); } } /** * Creates the data source manager. * * @param dataSourceXmlFile * @return DataSourceManager * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception * @see DataSource.xsd */ public static DataSourceManager createDataSourceManager(final String dataSourceXmlFile) throws UncheckedIOException, UncheckedSQLException { InputStream is = null; try { is = new FileInputStream(Configuration.findFile(dataSourceXmlFile)); return createDataSourceManager(is, dataSourceXmlFile); } catch (IOException e) { throw new UncheckedIOException(e); } finally { IOUtil.close(is); } } /** * Creates the data source manager. * * @param dataSourceXmlInputStream * @return DataSourceManager * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception * @see DataSource.xsd */ public static DataSourceManager createDataSourceManager(final InputStream dataSourceXmlInputStream) throws UncheckedIOException, UncheckedSQLException { return createDataSourceManager(dataSourceXmlInputStream, CURRENT_DIR_PATH); } /** The Constant PROPERTIES. */ private static final String PROPERTIES = "properties"; /** The Constant RESOURCE. */ private static final String RESOURCE = "resource"; /** * Creates the data source manager. * * @param dataSourceXmlInputStream * @param dataSourceXmlFile * @return * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception */ private static DataSourceManager createDataSourceManager(final InputStream dataSourceXmlInputStream, final String dataSourceXmlFile) throws UncheckedIOException, UncheckedSQLException { DocumentBuilder domParser = XMLUtil.createDOMParser(); Document doc = null; try { doc = domParser.parse(dataSourceXmlInputStream); Element rootElement = doc.getDocumentElement(); final Map props = new HashMap<>(); List propertiesElementList = XMLUtil.getElementsByTagName(rootElement, PROPERTIES); if (N.notNullOrEmpty(propertiesElementList)) { for (Element propertiesElement : propertiesElementList) { File resourcePropertiesFile = Configuration.findFileByFile(new File(dataSourceXmlFile), propertiesElement.getAttribute(RESOURCE)); java.util.Properties properties = new java.util.Properties(); InputStream is = null; try { is = new FileInputStream(resourcePropertiesFile); if (resourcePropertiesFile.getName().endsWith(".xml")) { properties.loadFromXML(is); } else { properties.load(is); } } finally { IOUtil.close(is); } for (Object key : properties.keySet()) { props.put((String) key, (String) properties.get(key)); } } } String nodeName = rootElement.getNodeName(); if (nodeName.equals(DataSourceManagerConfiguration.DATA_SOURCE_MANAGER)) { DataSourceManagerConfiguration config = new DataSourceManagerConfiguration(rootElement, props); return new SQLDataSourceManager(config); } else if (nodeName.equals(DataSourceConfiguration.DATA_SOURCE)) { DataSourceConfiguration config = new DataSourceConfiguration(rootElement, props); return new SimpleDataSourceManager(new SQLDataSource(config)); } else { throw new AbacusException("Unknown xml format with root element: " + nodeName); } } catch (SAXException e) { throw new ParseException(e); } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Creates the data source. * * @param dataSourceFile * @return * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception * @see DataSource.xsd */ public static DataSource createDataSource(final String dataSourceFile) throws UncheckedIOException, UncheckedSQLException { InputStream is = null; try { is = new FileInputStream(Configuration.findFile(dataSourceFile)); return createDataSource(is, dataSourceFile); } catch (IOException e) { throw new UncheckedIOException(e); } finally { IOUtil.close(is); } } /** * Creates the data source. * * @param dataSourceInputStream * @return * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception * @see DataSource.xsd */ public static DataSource createDataSource(final InputStream dataSourceInputStream) throws UncheckedIOException, UncheckedSQLException { return createDataSource(dataSourceInputStream, CURRENT_DIR_PATH); } /** * Creates the data source. * * @param dataSourceInputStream * @param dataSourceFile * @return * @throws UncheckedIOException the unchecked IO exception * @throws UncheckedSQLException the unchecked SQL exception */ private static DataSource createDataSource(final InputStream dataSourceInputStream, final String dataSourceFile) throws UncheckedIOException, UncheckedSQLException { final String dataSourceString = IOUtil.readString(dataSourceInputStream); if (CURRENT_DIR_PATH.equals(dataSourceFile) || dataSourceFile.endsWith(".xml")) { try { return createDataSourceManager(new ByteArrayInputStream(dataSourceString.getBytes())).getPrimaryDataSource(); } catch (ParseException e) { // ignore. } catch (UncheckedIOException e) { // ignore. } } final Map newProps = new HashMap<>(); final java.util.Properties properties = new java.util.Properties(); try { properties.load(new ByteArrayInputStream(dataSourceString.getBytes())); Object value = null; for (Object key : properties.keySet()) { value = properties.get(key); newProps.put(key.toString().trim(), value.toString().trim()); } } catch (IOException e) { throw new UncheckedIOException(e); } return new SQLDataSource(newProps); } /** * Creates the data source. * * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static DataSource createDataSource(final String url, final String user, final String password) throws UncheckedSQLException { return createDataSource(getDriverClasssByUrl(url), url, user, password); } /** * Creates the data source. * * @param driver * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static DataSource createDataSource(final String driver, final String url, final String user, final String password) throws UncheckedSQLException { final Class extends Driver> driverClass = ClassUtil.forClass(driver); return createDataSource(driverClass, url, user, password); } /** * Creates the data source. * * @param driverClass * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static DataSource createDataSource(final Class extends Driver> driverClass, final String url, final String user, final String password) throws UncheckedSQLException { N.checkArgNotNullOrEmpty(url, "url"); final Map props = new HashMap<>(); props.put(DRIVER, driverClass.getCanonicalName()); props.put(URL, url); props.put(USER, user); props.put(PASSWORD, password); return createDataSource(props); } /** * Creates the data source. * * @param props refer to Connection.xsd for the supported properties. * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static DataSource createDataSource(final Map props) throws UncheckedSQLException { final String driver = (String) props.get(DRIVER); if (N.isNullOrEmpty(driver)) { final String url = (String) props.get(URL); if (N.isNullOrEmpty(url)) { throw new IllegalArgumentException("Url is not specified"); } final Map tmp = new HashMap<>(props); tmp.put(DRIVER, getDriverClasssByUrl(url).getCanonicalName()); return new SQLDataSource(tmp); } else { return new SQLDataSource(props); } } // /** // * // * @param sqlDataSource // * @return // * @deprecated // */ // @Deprecated // public static DataSource wrap(final javax.sql.DataSource sqlDataSource) { // return sqlDataSource instanceof DataSource ? ((DataSource) sqlDataSource) : new SimpleDataSource(sqlDataSource); // } /** * Creates the connection. * * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static Connection createConnection(final String url, final String user, final String password) throws UncheckedSQLException { return createConnection(getDriverClasssByUrl(url), url, user, password); } /** * Gets the driver classs by url. * * @param url * @return */ private static Class extends Driver> getDriverClasssByUrl(final String url) { N.checkArgNotNullOrEmpty(url, "url"); Class extends Driver> driverClass = null; // jdbc:mysql://localhost:3306/abacustest if (url.indexOf("mysql") > 0 || StringUtil.indexOfIgnoreCase(url, "mysql") > 0) { driverClass = ClassUtil.forClass("com.mysql.jdbc.Driver"); // jdbc:postgresql://localhost:5432/abacustest } else if (url.indexOf("postgresql") > 0 || StringUtil.indexOfIgnoreCase(url, "postgresql") > 0) { driverClass = ClassUtil.forClass("org.postgresql.Driver"); // jdbc:h2:hsql:// : / } else if (url.indexOf("h2") > 0 || StringUtil.indexOfIgnoreCase(url, "h2") > 0) { driverClass = ClassUtil.forClass("org.h2.Driver"); // jdbc:hsqldb:hsql://localhost/abacustest } else if (url.indexOf("hsqldb") > 0 || StringUtil.indexOfIgnoreCase(url, "hsqldb") > 0) { driverClass = ClassUtil.forClass("org.hsqldb.jdbc.JDBCDriver"); // jdbc.url=jdbc:oracle:thin:@localhost:1521:abacustest } else if (url.indexOf("oracle") > 0 || StringUtil.indexOfIgnoreCase(url, "oracle") > 0) { driverClass = ClassUtil.forClass("oracle.jdbc.driver.OracleDriver"); // jdbc.url=jdbc:sqlserver://localhost:1433;Database=abacustest } else if (url.indexOf("sqlserver") > 0 || StringUtil.indexOfIgnoreCase(url, "sqlserver") > 0) { driverClass = ClassUtil.forClass("com.microsoft.sqlserver.jdbc.SQLServerDriver"); // jdbc:db2://localhost:50000/abacustest } else if (url.indexOf("db2") > 0 || StringUtil.indexOfIgnoreCase(url, "db2") > 0) { driverClass = ClassUtil.forClass("com.ibm.db2.jcc.DB2Driver"); } else { throw new IllegalArgumentException( "Can not identity the driver class by url: " + url + ". Only mysql, postgresql, hsqldb, sqlserver, oracle and db2 are supported currently"); } return driverClass; } /** * Creates the connection. * * @param driverClass * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static Connection createConnection(final String driverClass, final String url, final String user, final String password) throws UncheckedSQLException { Class extends Driver> cls = ClassUtil.forClass(driverClass); return createConnection(cls, url, user, password); } /** * Creates the connection. * * @param driverClass * @param url * @param user * @param password * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static Connection createConnection(final Class extends Driver> driverClass, final String url, final String user, final String password) throws UncheckedSQLException { try { DriverManager.registerDriver(N.newInstance(driverClass)); return DriverManager.getConnection(url, user, password); } catch (SQLException e) { throw new UncheckedSQLException("Failed to close create connection", e); } } /** The is in spring. */ private static boolean isInSpring = true; static { try { isInSpring = ClassUtil.forClass("org.springframework.jdbc.datasource.DataSourceUtils") != null; } catch (Throwable e) { isInSpring = false; } } /** * Spring Transaction is supported and Integrated. * If this method is called where a Spring transaction is started with the specified {@code DataSource}, * the {@code Connection} started the Spring Transaction will be returned. Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be returned. * * @param ds * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static Connection getConnection(final javax.sql.DataSource ds) throws UncheckedSQLException { if (isInSpring) { try { return org.springframework.jdbc.datasource.DataSourceUtils.getConnection(ds); } catch (NoClassDefFoundError e) { isInSpring = false; try { return ds.getConnection(); } catch (SQLException e1) { throw new UncheckedSQLException(e1); } } } else { try { return ds.getConnection(); } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * Spring Transaction is supported and Integrated. * If this method is called where a Spring transaction is started with the specified {@code DataSource}, * the specified {@code Connection} won't be returned to {@code DataSource}(Connection pool) until the transaction is committed or rolled back. Otherwise the specified {@code Connection} will be directly returned back to {@code DataSource}(Connection pool). * * @param conn * @param ds */ public static void releaseConnection(final Connection conn, final javax.sql.DataSource ds) { if (conn == null) { return; } if (isInSpring && ds != null) { try { org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(conn, ds); } catch (NoClassDefFoundError e) { isInSpring = false; JdbcUtil.closeQuietly(conn); } } else { JdbcUtil.closeQuietly(conn); } } /** * Creates the close handler. * * @param conn * @param ds * @return */ static Runnable createCloseHandler(final Connection conn, final javax.sql.DataSource ds) { return () -> releaseConnection(conn, ds); } /** * * @param rs * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final ResultSet rs) throws UncheckedSQLException { if (rs != null) { try { rs.close(); } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * * @param rs * @param closeStatement * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final ResultSet rs, final boolean closeStatement) throws UncheckedSQLException { close(rs, closeStatement, false); } /** * * @param rs * @param closeStatement * @param closeConnection * @throws IllegalArgumentException if {@code closeStatement = false} while {@code closeConnection = true}. * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final ResultSet rs, final boolean closeStatement, final boolean closeConnection) throws IllegalArgumentException, UncheckedSQLException { if (closeConnection && closeStatement == false) { throw new IllegalArgumentException("'closeStatement' can't be false while 'closeConnection' is true"); } if (rs == null) { return; } Connection conn = null; Statement stmt = null; try { if (closeStatement || closeConnection) { stmt = rs.getStatement(); } if (closeConnection && stmt != null) { conn = stmt.getConnection(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { close(rs, stmt, conn); } } /** * * @param stmt * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final Statement stmt) throws UncheckedSQLException { if (stmt != null) { try { if (stmt instanceof PreparedStatement) { try { ((PreparedStatement) stmt).clearParameters(); } catch (SQLException e) { logger.error("Failed to clear parameters", e); } } stmt.close(); } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * * @param conn * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final Connection conn) throws UncheckedSQLException { if (conn != null) { try { conn.close(); } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * * @param rs * @param stmt * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final ResultSet rs, final Statement stmt) throws UncheckedSQLException { try { if (rs != null) { rs.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { try { if (stmt != null) { if (stmt instanceof PreparedStatement) { try { ((PreparedStatement) stmt).clearParameters(); } catch (SQLException e) { logger.error("Failed to clear parameters", e); } } stmt.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * * @param stmt * @param conn * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final Statement stmt, final Connection conn) throws UncheckedSQLException { try { if (stmt != null) { if (stmt instanceof PreparedStatement) { try { ((PreparedStatement) stmt).clearParameters(); } catch (SQLException e) { logger.error("Failed to clear parameters", e); } } stmt.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } } } /** * * @param rs * @param stmt * @param conn * @throws UncheckedSQLException the unchecked SQL exception */ public static void close(final ResultSet rs, final Statement stmt, final Connection conn) throws UncheckedSQLException { try { if (rs != null) { rs.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { try { if (stmt != null) { if (stmt instanceof PreparedStatement) { try { ((PreparedStatement) stmt).clearParameters(); } catch (SQLException e) { logger.error("Failed to clear parameters", e); } } stmt.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e) { throw new UncheckedSQLException(e); } } } } /** * Unconditionally close an ResultSet
. ** Equivalent to {@link ResultSet#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param rs */ public static void closeQuietly(final ResultSet rs) { closeQuietly(rs, null, null); } /** * * @param rs * @param closeStatement * @throws UncheckedSQLException the unchecked SQL exception */ public static void closeQuietly(final ResultSet rs, final boolean closeStatement) throws UncheckedSQLException { closeQuietly(rs, closeStatement, false); } /** * * @param rs * @param closeStatement * @param closeConnection * @throws IllegalArgumentException if {@code closeStatement = false} while {@code closeConnection = true}. */ public static void closeQuietly(final ResultSet rs, final boolean closeStatement, final boolean closeConnection) throws IllegalArgumentException { if (closeConnection && closeStatement == false) { throw new IllegalArgumentException("'closeStatement' can't be false while 'closeConnection' is true"); } if (rs == null) { return; } Connection conn = null; Statement stmt = null; try { if (closeStatement || closeConnection) { stmt = rs.getStatement(); } if (closeConnection && stmt != null) { conn = stmt.getConnection(); } } catch (SQLException e) { logger.error("Failed to get Statement or Connection by ResultSet", e); } finally { closeQuietly(rs, stmt, conn); } } /** * Unconditionally close an
Statement
. ** Equivalent to {@link Statement#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param stmt */ public static void closeQuietly(final Statement stmt) { closeQuietly(null, stmt, null); } /** * Unconditionally close an
Connection
. ** Equivalent to {@link Connection#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param conn */ public static void closeQuietly(final Connection conn) { closeQuietly(null, null, conn); } /** * Unconditionally close the
ResultSet, Statement
. ** Equivalent to {@link ResultSet#close()}, {@link Statement#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param rs * @param stmt */ public static void closeQuietly(final ResultSet rs, final Statement stmt) { closeQuietly(rs, stmt, null); } /** * Unconditionally close the
Statement, Connection
. ** Equivalent to {@link Statement#close()}, {@link Connection#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param stmt * @param conn */ public static void closeQuietly(final Statement stmt, final Connection conn) { closeQuietly(null, stmt, conn); } /** * Unconditionally close the
ResultSet, Statement, Connection
. ** Equivalent to {@link ResultSet#close()}, {@link Statement#close()}, {@link Connection#close()}, except any exceptions will be ignored. * This is typically used in finally blocks. * * @param rs * @param stmt * @param conn */ public static void closeQuietly(final ResultSet rs, final Statement stmt, final Connection conn) { if (rs != null) { try { rs.close(); } catch (Exception e) { logger.error("Failed to close ResultSet", e); } } if (stmt != null) { if (stmt instanceof PreparedStatement) { try { ((PreparedStatement) stmt).clearParameters(); } catch (Exception e) { logger.error("Failed to clear parameters", e); } } try { stmt.close(); } catch (Exception e) { logger.error("Failed to close Statement", e); } } if (conn != null) { try { conn.close(); } catch (Exception e) { logger.error("Failed to close Connection", e); } } } /** * * @param rs * @param n the count of row to move ahead. * @return * @throws SQLException the SQL exception */ public static int skip(final ResultSet rs, int n) throws SQLException { return skip(rs, (long) n); } /** * * @param rs * @param n the count of row to move ahead. * @return * @throws SQLException the SQL exception * @see {@link ResultSet#absolute(int)} */ public static int skip(final ResultSet rs, long n) throws SQLException { return InternalJdbcUtil.skip(rs, n); } /** * Gets the column count. * * @param rs * @return * @throws SQLException the SQL exception */ public static int getColumnCount(ResultSet rs) throws SQLException { return rs.getMetaData().getColumnCount(); } /** * Gets the column name list. * * @param conn * @param tableName * @return * @throws SQLException the SQL exception */ public static List
getColumnNameList(final Connection conn, final String tableName) throws SQLException { final String query = "SELECT * FROM " + tableName + " WHERE 1 > 2"; PreparedStatement stmt = null; ResultSet rs = null; try { stmt = prepareStatement(conn, query); rs = stmt.executeQuery(); final ResultSetMetaData metaData = rs.getMetaData(); final int columnCount = metaData.getColumnCount(); final List columnNameList = new ArrayList<>(columnCount); for (int i = 1, n = columnCount + 1; i < n; i++) { columnNameList.add(metaData.getColumnName(i)); } return columnNameList; } finally { closeQuietly(rs, stmt); } } /** * Gets the column label list. * * @param rs * @return * @throws SQLException the SQL exception */ public static List getColumnLabelList(ResultSet rs) throws SQLException { return InternalJdbcUtil.getColumnLabelList(rs); } /** * Gets the column label. * * @param rsmd * @param columnIndex * @return * @throws SQLException the SQL exception */ public static String getColumnLabel(final ResultSetMetaData rsmd, final int columnIndex) throws SQLException { return InternalJdbcUtil.getColumnLabel(rsmd, columnIndex); } /** * Gets the column value. * * @param rs * @param columnIndex * @return * @throws SQLException the SQL exception */ public static Object getColumnValue(final ResultSet rs, final int columnIndex) throws SQLException { return InternalJdbcUtil.getColumnValue(rs, columnIndex); } /** * Gets the column value. * * @param rs * @param columnLabel * @return * @throws SQLException the SQL exception */ public static Object getColumnValue(final ResultSet rs, final String columnLabel) throws SQLException { return InternalJdbcUtil.getColumnValue(rs, columnLabel); } /** * Gets the column value. * * @param * @param targetClass * @param rs * @param columnIndex * @return * @throws SQLException the SQL exception */ public static T getColumnValue(final Class targetClass, final ResultSet rs, final int columnIndex) throws SQLException { return N. typeOf(targetClass).get(rs, columnIndex); } /** * Gets the column value. * * @param * @param targetClass * @param rs * @param columnLabel * @return * @throws SQLException the SQL exception */ public static T getColumnValue(final Class targetClass, final ResultSet rs, final String columnLabel) throws SQLException { return N. typeOf(targetClass).get(rs, columnLabel); } /** * Refer to: {@code beginTransaction(javax.sql.DataSource, IsolationLevel, boolean)}. * * @param dataSource * @return * @throws UncheckedSQLException the unchecked SQL exception * @see {@link #beginTransaction(javax.sql.DataSource, IsolationLevel, boolean)} */ public static SQLTransaction beginTransaction(final javax.sql.DataSource dataSource) throws UncheckedSQLException { return beginTransaction(dataSource, IsolationLevel.DEFAULT); } /** * Refer to: {@code beginTransaction(javax.sql.DataSource, IsolationLevel, boolean)}. * * @param dataSource * @param isolationLevel * @return * @throws UncheckedSQLException the unchecked SQL exception * @see {@link #beginTransaction(javax.sql.DataSource, IsolationLevel, boolean)} */ public static SQLTransaction beginTransaction(final javax.sql.DataSource dataSource, final IsolationLevel isolationLevel) throws UncheckedSQLException { return beginTransaction(dataSource, isolationLevel, false); } /** * Starts a global transaction which will be shared by all in-line database query with the same {@code DataSource} in the same thread, * including methods: {@code JdbcUtil.beginTransaction/prepareQuery/prepareNamedQuery/prepareCallableQuery, SQLExecutor(Mapper).beginTransaction/get/insert/batchInsert/update/batchUpdate/query/list/findFirst/...} * *
* Spring Transaction is supported and Integrated. * If this method is called at where a Spring transaction is started with the specified {@code DataSource}, * the {@code Connection} started the Spring Transaction will be used here. * That's to say the Spring transaction will have the final control on commit/roll back over the {@code Connection}. * *
*
* * Here is the general code pattern to work with {@code SQLTransaction}. * **** public void doSomethingA() { * ... * final SQLTransaction tranA = JdbcUtil.beginTransaction(dataSource1, isolation); * * try { * ... * doSomethingB(); // Share the same transaction 'tranA' because they're in the same thread and start transaction with same DataSource 'dataSource1'. * ... * doSomethingC(); // won't share the same transaction 'tranA' although they're in the same thread but start transaction with different DataSource 'dataSource2'. * ... * tranA.commit(); * } finally { * tranA.rollbackIfNotCommitted(); * } * } * * public void doSomethingB() { * ... * final SQLTransaction tranB = JdbcUtil.beginTransaction(dataSource1, isolation); * try { * // do your work with the conn... * ... * tranB.commit(); * } finally { * tranB.rollbackIfNotCommitted(); * } * } * * public void doSomethingC() { * ... * final SQLTransaction tranC = JdbcUtil.beginTransaction(dataSource2, isolation); * try { * // do your work with the conn... * ... * tranC.commit(); * } finally { * tranC.rollbackIfNotCommitted(); * } * } *
** * @param dataSource * @param isolationLevel * @param isForUpdateOnly * @return * @throws UncheckedSQLException the unchecked SQL exception * @see {@link #getConnection(javax.sql.DataSource)} * @see {@link #releaseConnection(Connection, javax.sql.DataSource)} * @see SQLExecutor#beginTransaction(IsolationLevel, boolean, JdbcSettings) */ public static SQLTransaction beginTransaction(final javax.sql.DataSource dataSource, final IsolationLevel isolationLevel, final boolean isForUpdateOnly) throws UncheckedSQLException { N.checkArgNotNull(dataSource, "dataSource"); N.checkArgNotNull(isolationLevel, "isolationLevel"); SQLTransaction tran = SQLTransaction.getTransaction(dataSource, CreatedBy.JDBC_UTIL); if (tran == null) { Connection conn = null; boolean noException = false; try { conn = getConnection(dataSource); tran = new SQLTransaction(dataSource, conn, isolationLevel, CreatedBy.JDBC_UTIL, true); tran.incrementAndGetRef(isolationLevel, isForUpdateOnly); noException = true; } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { if (noException == false) { releaseConnection(conn, dataSource); } } logger.info("Create a new SQLTransaction(id={})", tran.id()); SQLTransaction.putTransaction(tran); } else { logger.info("Reusing the existing SQLTransaction(id={})", tran.id()); tran.incrementAndGetRef(isolationLevel, isForUpdateOnly); } return tran; } /** * * @param* public void doSomethingA() { * ... * final SQLTransaction tranA = JdbcUtil.beginTransaction(dataSource1, isolation); * boolean flagToCommit = false; * try { * // do your work with the conn... * ... * flagToCommit = true; * } finally { * if (flagToCommit) { * tranA.commit(); * } else { * tranA.rollbackIfNotCommitted(); * } * } * } *
** @param * @param ds * @param callable * @return * @throws E */ @Beta public static T doInTransaction(final javax.sql.DataSource ds, final Try.Callable callable) throws E { final SQLTransaction tran = JdbcUtil.beginTransaction(ds); T result = null; try { result = callable.call(); tran.commit(); } finally { tran.rollbackIfNotCommitted(); } return result; } /** * * @param * @param * @param ds * @param func * @return * @throws E */ @Beta public static T doInTransaction(final javax.sql.DataSource ds, final Try.Function func) throws E { final SQLTransaction tran = JdbcUtil.beginTransaction(ds); T result = null; try { result = func.apply(ds); tran.commit(); } finally { tran.rollbackIfNotCommitted(); } return result; } /** * * @param * @param ds * @param runnable * @return * @throws E */ @Beta public static void runInTransaction(final javax.sql.DataSource ds, final Try.Runnable runnable) throws E { final SQLTransaction tran = JdbcUtil.beginTransaction(ds); try { runnable.run(); tran.commit(); } finally { tran.rollbackIfNotCommitted(); } } /** * * @param * @param ds * @param action * @return * @throws E */ @Beta public static void runInTransaction(final javax.sql.DataSource ds, final Try.Consumer action) throws E { final SQLTransaction tran = JdbcUtil.beginTransaction(ds); try { action.accept(ds); tran.commit(); } finally { tran.rollbackIfNotCommitted(); } } /** * Gets the SQL operation. * * @param sql * @return */ static SQLOperation getSQLOperation(String sql) { if (StringUtil.startsWithIgnoreCase(sql.trim(), "select ")) { return SQLOperation.SELECT; } else if (StringUtil.startsWithIgnoreCase(sql.trim(), "update ")) { return SQLOperation.UPDATE; } else if (StringUtil.startsWithIgnoreCase(sql.trim(), "insert ")) { return SQLOperation.INSERT; } else if (StringUtil.startsWithIgnoreCase(sql.trim(), "delete ")) { return SQLOperation.DELETE; } else { for (SQLOperation so : SQLOperation.values()) { if (StringUtil.startsWithIgnoreCase(sql.trim(), so.name())) { return so; } } } throw new IllegalArgumentException("Unsupported sql operation: " + sql.substring(0, sql.indexOf(' '))); } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param sql * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedQuery prepareQuery(final javax.sql.DataSource ds, final String sql) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareQuery(tran.connection(), sql); } else { PreparedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareQuery(conn, sql).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param sql * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedQuery prepareQuery(final javax.sql.DataSource ds, final String sql, final boolean autoGeneratedKeys) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareQuery(tran.connection(), sql, autoGeneratedKeys); } else { PreparedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareQuery(conn, sql, autoGeneratedKeys).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * * @param ds * @param sql * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final javax.sql.DataSource ds, final String sql, final int[] returnColumnIndexes) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareQuery(tran.connection(), sql, returnColumnIndexes); } else { PreparedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareQuery(conn, sql, returnColumnIndexes).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * * @param ds * @param sql * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final javax.sql.DataSource ds, final String sql, final String[] returnColumnNames) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareQuery(tran.connection(), sql, returnColumnNames); } else { PreparedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareQuery(conn, sql, returnColumnNames).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param sql * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code PreparedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedQuery prepareQuery(final javax.sql.DataSource ds, final String sql, final Try.BiFunction stmtCreator) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareQuery(tran.connection(), sql, stmtCreator); } else { PreparedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareQuery(conn, sql, stmtCreator).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * Never write below code because it will definitely cause {@code Connection} leak: * ** * @param conn the specified {@code conn} won't be close after this query is executed. * @param sql * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final Connection conn, final String sql) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); return new PreparedQuery(conn.prepareStatement(sql)); } /** * * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareQuery(dataSource.getConnection(), sql); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param sql * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final Connection conn, final String sql, final boolean autoGeneratedKeys) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); return new PreparedQuery(conn.prepareStatement(sql, autoGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS)); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareQuery(dataSource.getConnection(), sql, autoGeneratedKeys); *
*** * @param conn * @param sql * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final Connection conn, final String sql, final int[] returnColumnIndexes) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); N.checkArgNotNullOrEmpty(returnColumnIndexes, "returnColumnIndexes"); return new PreparedQuery(conn.prepareStatement(sql, returnColumnIndexes)); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareQuery(dataSource.getConnection(), sql, returnColumnIndexes); *
*** * @param conn * @param sql * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static PreparedQuery prepareQuery(final Connection conn, final String sql, final String[] returnColumnNames) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); N.checkArgNotNullOrEmpty(returnColumnNames, "returnColumnNames"); return new PreparedQuery(conn.prepareStatement(sql, returnColumnNames)); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareQuery(dataSource.getConnection(), sql, returnColumnNames); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param sql * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code PreparedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see {@link JdbcUtil#prepareStatement(Connection, String, Object...)} */ public static PreparedQuery prepareQuery(final Connection conn, final String sql, final Try.BiFunction* JdbcUtil.prepareQuery(dataSource.getConnection(), sql, stmtCreator); *
*stmtCreator) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); N.checkArgNotNull(stmtCreator, "stmtCreator"); return new PreparedQuery(stmtCreator.apply(conn, sql)); } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final String namedSql) throws SQLException { final SQLTransaction tran = getTransaction(ds, namedSql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSql); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSql).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final String namedSql, final boolean autoGeneratedKeys) throws SQLException { final SQLTransaction tran = getTransaction(ds, namedSql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSql, autoGeneratedKeys); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSql, autoGeneratedKeys).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final String namedSql, final int[] returnColumnIndexes) throws SQLException { final SQLTransaction tran = getTransaction(ds, namedSql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSql, returnColumnIndexes); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSql, returnColumnIndexes).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final String namedSql, final String[] returnColumnNames) throws SQLException { final SQLTransaction tran = getTransaction(ds, namedSql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSql, returnColumnNames); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSql, returnColumnNames).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code NamedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final String namedSql, final Try.BiFunction stmtCreator) throws SQLException { final SQLTransaction tran = getTransaction(ds, namedSql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSql, stmtCreator); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSql, stmtCreator).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * Never write below code because it will definitely cause {@code Connection} leak: * ** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final String namedSql) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSql, "namedSql"); final NamedSQL namedSQL = createNamedSQL(namedSql); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL()), namedSQL); } /** * * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSql); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final String namedSql, final boolean autoGeneratedKeys) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSql, "namedSql"); final NamedSQL namedSQL = createNamedSQL(namedSql); return new NamedQuery( conn.prepareStatement(namedSQL.getParameterizedSQL(), autoGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSql, autoGeneratedKeys); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final String namedSql, final int[] returnColumnIndexes) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSql, "namedSql"); N.checkArgNotNullOrEmpty(returnColumnIndexes, "returnColumnIndexes"); final NamedSQL namedSQL = createNamedSQL(namedSql); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL(), returnColumnIndexes), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSql); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final String namedSql, final String[] returnColumnNames) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSql, "namedSql"); N.checkArgNotNullOrEmpty(returnColumnNames, "returnColumnNames"); final NamedSQL namedSQL = createNamedSQL(namedSql); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL(), returnColumnNames), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSql); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSql for example {@code SELECT first_name, last_name FROM account where id = :id} * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code NamedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see {@link JdbcUtil#prepareStatement(Connection, String, Object...)} */ public static NamedQuery prepareNamedQuery(final Connection conn, final String namedSql, final Try.BiFunction* JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSql, stmtCreator); *
*stmtCreator) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSql, "namedSql"); N.checkArgNotNull(stmtCreator, "stmtCreator"); final NamedSQL namedSQL = createNamedSQL(namedSql); return new NamedQuery(stmtCreator.apply(conn, namedSQL.getParameterizedSQL()), namedSQL); } /** * Creates the named SQL. * * @param namedSql * @return */ private static NamedSQL createNamedSQL(final String namedSql) { N.checkArgNotNullOrEmpty(namedSql, "namedSql"); final NamedSQL namedSQL = NamedSQL.parse(namedSql); validateNamedSQL(namedSQL); return namedSQL; } private static void validateNamedSQL(final NamedSQL namedSQL) { if (namedSQL.getNamedParameters().size() != namedSQL.getParameterCount()) { throw new IllegalArgumentException("\"" + namedSQL.getNamedSQL() + "\" is not a valid named sql:"); } } private static SQLTransaction getTransaction(final javax.sql.DataSource ds, final String sql, final CreatedBy createdBy) { final SQLOperation sqlOperation = JdbcUtil.getSQLOperation(sql); final SQLTransaction tran = SQLTransaction.getTransaction(ds, createdBy); if (tran == null || (tran.isForUpdateOnly() && sqlOperation == SQLOperation.SELECT)) { return null; } else { return tran; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final NamedSQL namedSQL) throws SQLException { validateNamedSQL(namedSQL); final SQLTransaction tran = getTransaction(ds, namedSQL.getParameterizedSQL(), CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSQL); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSQL).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final NamedSQL namedSQL, final boolean autoGeneratedKeys) throws SQLException { validateNamedSQL(namedSQL); final SQLTransaction tran = getTransaction(ds, namedSQL.getParameterizedSQL(), CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSQL, autoGeneratedKeys); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSQL, autoGeneratedKeys).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final NamedSQL namedSQL, final int[] returnColumnIndexes) throws SQLException { validateNamedSQL(namedSQL); final SQLTransaction tran = getTransaction(ds, namedSQL.getParameterizedSQL(), CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSQL, returnColumnIndexes); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSQL, returnColumnIndexes).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final NamedSQL namedSQL, final String[] returnColumnNames) throws SQLException { validateNamedSQL(namedSQL); final SQLTransaction tran = getTransaction(ds, namedSQL.getParameterizedSQL(), CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSQL, returnColumnNames); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSQL, returnColumnNames).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code NamedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static NamedQuery prepareNamedQuery(final javax.sql.DataSource ds, final NamedSQL namedSQL, final Try.BiFunction stmtCreator) throws SQLException { validateNamedSQL(namedSQL); final SQLTransaction tran = getTransaction(ds, namedSQL.getParameterizedSQL(), CreatedBy.JDBC_UTIL); if (tran != null) { return prepareNamedQuery(tran.connection(), namedSQL, stmtCreator); } else { NamedQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareNamedQuery(conn, namedSQL, stmtCreator).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * Never write below code because it will definitely cause {@code Connection} leak: * ** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final NamedSQL namedSQL) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSQL, "namedSQL"); validateNamedSQL(namedSQL); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL()), namedSQL); } /** * * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSQL); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param autoGeneratedKeys * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final NamedSQL namedSQL, final boolean autoGeneratedKeys) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSQL, "namedSQL"); validateNamedSQL(namedSQL); return new NamedQuery( conn.prepareStatement(namedSQL.getParameterizedSQL(), autoGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSQL, autoGeneratedKeys); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnIndexes * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final NamedSQL namedSQL, final int[] returnColumnIndexes) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSQL, "namedSQL"); N.checkArgNotNullOrEmpty(returnColumnIndexes, "returnColumnIndexes"); validateNamedSQL(namedSQL); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL(), returnColumnIndexes), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSQL); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param returnColumnNames * @return * @throws SQLException the SQL exception */ public static NamedQuery prepareNamedQuery(final Connection conn, final NamedSQL namedSQL, final String[] returnColumnNames) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSQL, "namedSQL"); N.checkArgNotNullOrEmpty(returnColumnNames, "returnColumnNames"); validateNamedSQL(namedSQL); return new NamedQuery(conn.prepareStatement(namedSQL.getParameterizedSQL(), returnColumnNames), namedSQL); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSQL); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param namedSQL for example {@code SELECT first_name, last_name FROM account where id = :id} * @param stmtCreator the created {@code PreparedStatement} will be closed after any execution methods in {@code NamedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see {@link JdbcUtil#prepareStatement(Connection, String, Object...)} */ public static NamedQuery prepareNamedQuery(final Connection conn, final NamedSQL namedSQL, final Try.BiFunction* JdbcUtil.prepareNamedQuery(dataSource.getConnection(), namedSQL, stmtCreator); *
*stmtCreator) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(namedSQL, "namedSQL"); N.checkArgNotNull(stmtCreator, "stmtCreator"); validateNamedSQL(namedSQL); return new NamedQuery(stmtCreator.apply(conn, namedSQL.getParameterizedSQL()), namedSQL); } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param sql * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedCallableQuery prepareCallableQuery(final javax.sql.DataSource ds, final String sql) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareCallableQuery(tran.connection(), sql); } else { PreparedCallableQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareCallableQuery(conn, sql).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * If this method is called where a transaction is started by {@code JdbcUtil.beginTransaction} or in {@code Spring} with the same {@code DataSource} in the same thread, * the {@code Connection} started the Transaction will be used here. * Otherwise a {@code Connection} directly from the specified {@code DataSource}(Connection pool) will be borrowed and used. * * @param ds * @param sql * @param stmtCreator the created {@code CallableStatement} will be closed after any execution methods in {@code PreparedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedCallableQuery prepareCallableQuery(final javax.sql.DataSource ds, final String sql, final Try.BiFunction stmtCreator) throws SQLException { final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return prepareCallableQuery(tran.connection(), sql, stmtCreator); } else { PreparedCallableQuery result = null; Connection conn = null; try { conn = getConnection(ds); result = prepareCallableQuery(conn, sql, stmtCreator).onClose(createCloseHandler(conn, ds)); } finally { if (result == null) { releaseConnection(conn, ds); } } return result; } } /** * Never write below code because it will definitely cause {@code Connection} leak: * ** * @param conn the specified {@code conn} won't be close after this query is executed. * @param sql * @return * @throws SQLException the SQL exception * @see #getConnection(javax.sql.DataSource) * @see #releaseConnection(Connection, javax.sql.DataSource) */ public static PreparedCallableQuery prepareCallableQuery(final Connection conn, final String sql) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); return new PreparedCallableQuery(conn.prepareCall(sql)); } /** * Never write below code because it will definitely cause {@code Connection} leak: ** JdbcUtil.prepareCallableQuery(dataSource.getConnection(), sql); *
*** * @param conn the specified {@code conn} won't be close after this query is executed. * @param sql * @param stmtCreator the created {@code CallableStatement} will be closed after any execution methods in {@code PreparedQuery/PreparedCallableQuery} is called. * An execution method is a method which will trigger the backed {@code PreparedStatement/CallableStatement} to be executed, for example: get/query/queryForInt/Long/../findFirst/list/execute/.... * @return * @throws SQLException the SQL exception * @see {@link JdbcUtil#prepareCall(Connection, String, Object...)} */ public static PreparedCallableQuery prepareCallableQuery(final Connection conn, final String sql, final Try.BiFunction* JdbcUtil.prepareCallableQuery(dataSource.getConnection(), sql, stmtCreator); *
*stmtCreator) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); N.checkArgNotNull(stmtCreator, "stmtCreator"); return new PreparedCallableQuery(stmtCreator.apply(conn, sql)); } /** * * @param conn * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs static PreparedStatement prepareStatement(final Connection conn, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); final NamedSQL namedSQL = NamedSQL.parse(sql); final PreparedStatement stmt = conn.prepareStatement(namedSQL.getParameterizedSQL()); if (N.notNullOrEmpty(parameters)) { StatementSetter.DEFAULT.setParameters(namedSQL, stmt, parameters); } return stmt; } /** * * @param conn * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs static CallableStatement prepareCall(final Connection conn, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); final NamedSQL namedSQL = NamedSQL.parse(sql); final CallableStatement stmt = conn.prepareCall(namedSQL.getParameterizedSQL()); if (N.notNullOrEmpty(parameters)) { StatementSetter.DEFAULT.setParameters(namedSQL, stmt, parameters); } return stmt; } /** * Batch prepare statement. * * @param conn * @param sql * @param parametersList * @return * @throws SQLException the SQL exception */ static PreparedStatement prepareBatchStatement(final Connection conn, final String sql, final List> parametersList) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); final NamedSQL namedSQL = NamedSQL.parse(sql); final PreparedStatement stmt = conn.prepareStatement(namedSQL.getParameterizedSQL()); for (Object parameters : parametersList) { StatementSetter.DEFAULT.setParameters(namedSQL, stmt, N.asArray(parameters)); stmt.addBatch(); } return stmt; } /** * * @param conn * @param sql * @param parametersList * @return * @throws SQLException the SQL exception */ static CallableStatement prepareBatchCall(final Connection conn, final String sql, final List> parametersList) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); final NamedSQL namedSQL = NamedSQL.parse(sql); final CallableStatement stmt = conn.prepareCall(namedSQL.getParameterizedSQL()); for (Object parameters : parametersList) { StatementSetter.DEFAULT.setParameters(namedSQL, stmt, N.asArray(parameters)); stmt.addBatch(); } return stmt; } /** * * @param ds * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs public static DataSet executeQuery(final DataSource ds, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(ds, "ds"); N.checkArgNotNull(sql, "sql"); final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return executeQuery(tran.connection(), sql, parameters); } else { final Connection conn = getConnection(ds); try { return executeQuery(conn, sql, parameters); } finally { JdbcUtil.closeQuietly(conn); } } } /** * * @param conn * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs public static DataSet executeQuery(final Connection conn, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); PreparedStatement stmt = null; ResultSet rs = null; try { stmt = prepareStatement(conn, sql, parameters); stmt.setFetchDirection(ResultSet.FETCH_FORWARD); rs = stmt.executeQuery(); return extractData(rs); } finally { closeQuietly(rs, stmt); } } /** * * @param stmt * @return * @throws SQLException the SQL exception */ public static DataSet executeQuery(final PreparedStatement stmt) throws SQLException { ResultSet rs = null; try { rs = stmt.executeQuery(); return extractData(rs); } finally { closeQuietly(rs); } } /** * * @param ds * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs public static int executeUpdate(final DataSource ds, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(ds, "ds"); N.checkArgNotNull(sql, "sql"); final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return executeUpdate(tran.connection(), sql, parameters); } else { final Connection conn = getConnection(ds); try { return executeUpdate(conn, sql, parameters); } finally { JdbcUtil.closeQuietly(conn); } } } /** * * @param conn * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs public static int executeUpdate(final Connection conn, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); PreparedStatement stmt = null; try { stmt = prepareStatement(conn, sql, parameters); return stmt.executeUpdate(); } finally { closeQuietly(stmt); } } /** * * @param ds * @param sql * @param listOfParameters * @return * @throws SQLException the SQL exception */ public static int executeBatchUpdate(final DataSource ds, final String sql, final List> listOfParameters) throws SQLException { return executeBatchUpdate(ds, sql, listOfParameters, JdbcUtil.DEFAULT_BATCH_SIZE); } /** * * @param ds * @param sql * @param listOfParameters * @param batchSize * @return * @throws SQLException the SQL exception */ public static int executeBatchUpdate(final DataSource ds, final String sql, final List> listOfParameters, final int batchSize) throws SQLException { N.checkArgNotNull(ds, "ds"); N.checkArgNotNull(sql, "sql"); N.checkArgPositive(batchSize, "batchSize"); final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return executeBatchUpdate(tran.connection(), sql, listOfParameters, batchSize); } else if (listOfParameters.size() <= batchSize) { final Connection conn = getConnection(ds); try { return executeBatchUpdate(conn, sql, listOfParameters, batchSize); } finally { JdbcUtil.closeQuietly(conn); } } else { final SQLTransaction tran2 = JdbcUtil.beginTransaction(ds); int ret = 0; try { ret = executeBatchUpdate(tran2.connection(), sql, listOfParameters, batchSize); tran2.commit(); } finally { tran2.rollbackIfNotCommitted(); } return ret; } } /** * Execute batch update. * * @param conn * @param sql * @param listOfParameters * @return * @throws SQLException the SQL exception */ public static int executeBatchUpdate(final Connection conn, final String sql, final List> listOfParameters) throws SQLException { return executeBatchUpdate(conn, sql, listOfParameters, JdbcUtil.DEFAULT_BATCH_SIZE); } /** * Execute batch update. * * @param conn * @param sql * @param listOfParameters * @param batchSize * @return * @throws SQLException the SQL exception */ public static int executeBatchUpdate(final Connection conn, final String sql, final List> listOfParameters, final int batchSize) throws SQLException { N.checkArgNotNull(conn); N.checkArgNotNull(sql); N.checkArgPositive(batchSize, "batchSize"); if (N.isNullOrEmpty(listOfParameters)) { return 0; } final NamedSQL namedSQL = NamedSQL.parse(sql); final boolean originalAutoCommit = conn.getAutoCommit(); PreparedStatement stmt = null; boolean noException = false; try { if (originalAutoCommit && listOfParameters.size() > batchSize) { conn.setAutoCommit(false); } stmt = conn.prepareStatement(namedSQL.getParameterizedSQL()); int res = 0; int idx = 0; for (Object parameters : listOfParameters) { StatementSetter.DEFAULT.setParameters(namedSQL, stmt, parameters); stmt.addBatch(); if (++idx % batchSize == 0) { res += N.sum(stmt.executeBatch()); stmt.clearBatch(); } } if (idx % batchSize != 0) { res += N.sum(stmt.executeBatch()); stmt.clearBatch(); } noException = true; return res; } finally { if (originalAutoCommit && listOfParameters.size() > batchSize) { try { if (noException) { conn.commit(); } else { conn.rollback(); } } finally { try { conn.setAutoCommit(true); } finally { JdbcUtil.closeQuietly(stmt); } } } else { JdbcUtil.closeQuietly(stmt); } } } /** * * @param ds * @param sql * @param parameters * @return * @throws SQLException the SQL exception */ @SafeVarargs public static boolean execute(final DataSource ds, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(ds, "ds"); N.checkArgNotNull(sql, "sql"); final SQLTransaction tran = getTransaction(ds, sql, CreatedBy.JDBC_UTIL); if (tran != null) { return execute(tran.connection(), sql, parameters); } else { final Connection conn = getConnection(ds); try { return execute(conn, sql, parameters); } finally { JdbcUtil.closeQuietly(conn); } } } /** * * @param conn * @param sql * @param parameters * @return true, if successful * @throws SQLException the SQL exception */ @SafeVarargs public static boolean execute(final Connection conn, final String sql, final Object... parameters) throws SQLException { N.checkArgNotNull(conn, "conn"); N.checkArgNotNull(sql, "sql"); PreparedStatement stmt = null; try { stmt = prepareStatement(conn, sql, parameters); return stmt.execute(); } finally { closeQuietly(stmt); } } /** * * @param rs * @return * @throws SQLException the SQL exception */ public static DataSet extractData(final ResultSet rs) throws SQLException { return extractData(rs, false); } /** * * @param rs * @param closeResultSet * @return * @throws SQLException the SQL exception */ public static DataSet extractData(final ResultSet rs, final boolean closeResultSet) throws SQLException { return extractData(rs, 0, Integer.MAX_VALUE, closeResultSet); } /** * * @param rs * @param offset * @param count * @return * @throws SQLException the SQL exception */ public static DataSet extractData(final ResultSet rs, final int offset, final int count) throws SQLException { return extractData(rs, offset, count, false); } /** * * @param rs * @param offset * @param count * @param closeResultSet * @return * @throws SQLException the SQL exception */ public static DataSet extractData(final ResultSet rs, final int offset, final int count, final boolean closeResultSet) throws SQLException { return extractData(rs, offset, count, RowFilter.ALWAYS_TRUE, closeResultSet); } /** * * @param rs * @param offset * @param count * @param filter * @param closeResultSet * @return * @throws SQLException the SQL exception */ public static DataSet extractData(final ResultSet rs, int offset, int count, final RowFilter filter, final boolean closeResultSet) throws SQLException { N.checkArgNotNull(rs, "ResultSet"); N.checkArgNotNegative(offset, "offset"); N.checkArgNotNegative(count, "count"); N.checkArgNotNull(filter, "filter"); try { // TODO [performance improvement]. it will improve performance a lot if MetaData is cached. final ResultSetMetaData rsmd = rs.getMetaData(); final int columnCount = rsmd.getColumnCount(); final List columnNameList = new ArrayList<>(columnCount); final List > columnList = new ArrayList<>(columnCount); for (int i = 0; i < columnCount;) { columnNameList.add(JdbcUtil.getColumnLabel(rsmd, ++i)); columnList.add(new ArrayList<>()); } JdbcUtil.skip(rs, offset); while (count > 0 && rs.next()) { if (filter == null || filter.test(rs)) { for (int i = 0; i < columnCount;) { columnList.get(i).add(JdbcUtil.getColumnValue(rs, ++i)); } count--; } } // return new RowDataSet(null, entityClass, columnNameList, columnList); return new RowDataSet(columnNameList, columnList); } finally { if (closeResultSet) { closeQuietly(rs); } } } /** * Does table exist. * * @param conn * @param tableName * @return true, if successful */ public static boolean doesTableExist(final Connection conn, final String tableName) { try { executeQuery(conn, "SELECT 1 FROM " + tableName + " WHERE 1 > 2"); return true; } catch (SQLException e) { if (isTableNotExistsException(e)) { return false; } throw new UncheckedSQLException(e); } } /** * Returns {@code true} if succeed to create table, otherwise {@code false} is returned. * * @param conn * @param tableName * @param schema * @return true, if successful */ public static boolean createTableIfNotExists(final Connection conn, final String tableName, final String schema) { if (doesTableExist(conn, tableName)) { return false; } try { execute(conn, schema); return true; } catch (SQLException e) { return false; } } /** * Returns {@code true} if succeed to drop table, otherwise {@code false} is returned. * * @param conn * @param tableName * @return true, if successful */ public static boolean dropTableIfExists(final Connection conn, final String tableName) { try { if (doesTableExist(conn, tableName)) { execute(conn, "DROP TABLE " + tableName); return true; } } catch (SQLException e) { // ignore. } return false; } /** * Gets the named parameters. * * @param sql * @return */ public static List
getNamedParameters(String sql) { return NamedSQL.parse(sql).getNamedParameters(); } /** * Imports the data from DataSet
to database. * * @param dataset * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final Connection conn, final String insertSQL) throws UncheckedSQLException { return importData(dataset, dataset.columnNameList(), conn, insertSQL); } /** * Imports the data from* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * DataSet
to database. * * @param dataset * @param selectColumnNames * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final Collection* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * selectColumnNames, final Connection conn, final String insertSQL) throws UncheckedSQLException { return importData(dataset, selectColumnNames, 0, dataset.size(), conn, insertSQL); } /** * Imports the data from DataSet
to database. * * @param dataset * @param selectColumnNames * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final Collection* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * selectColumnNames, final int offset, final int count, final Connection conn, final String insertSQL) throws UncheckedSQLException { return importData(dataset, selectColumnNames, offset, count, conn, insertSQL, 200, 0); } /** * Imports the data from DataSet
to database. * * @param dataset * @param selectColumnNames * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param batchSize * @param batchInterval * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final Collection* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * selectColumnNames, final int offset, final int count, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval) throws UncheckedSQLException { return importData(dataset, selectColumnNames, offset, count, Fn.alwaysTrue(), conn, insertSQL, batchSize, batchInterval); } /** * Imports the data from DataSet
to database. * * @param* @param dataset * @param selectColumnNames * @param offset * @param count * @param filter * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: * * @param batchSize * @param batchInterval * @return * @throws UncheckedSQLException the unchecked SQL exception * @throws E the e */ public static* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * int importData(final DataSet dataset, final Collection selectColumnNames, final int offset, final int count, final Try.Predicate super Object[], E> filter, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval) throws UncheckedSQLException, E { PreparedStatement stmt = null; try { stmt = prepareStatement(conn, insertSQL); return importData(dataset, selectColumnNames, offset, count, filter, stmt, batchSize, batchInterval); } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { JdbcUtil.closeQuietly(stmt); } } /** * Imports the data from DataSet
to database. * * @param dataset * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final Connection conn, final String insertSQL, final Map* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * columnTypeMap) throws UncheckedSQLException { return importData(dataset, 0, dataset.size(), conn, insertSQL, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param dataset * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final int offset, final int count, final Connection conn, final String insertSQL, final Map* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * columnTypeMap) throws UncheckedSQLException { return importData(dataset, offset, count, conn, insertSQL, 200, 0, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param dataset * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param batchSize * @param batchInterval * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final int offset, final int count, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval, final Map* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * columnTypeMap) throws UncheckedSQLException { return importData(dataset, offset, count, Fn.alwaysTrue(), conn, insertSQL, batchSize, batchInterval, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param* @param dataset * @param offset * @param count * @param filter * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: * * @param batchSize * @param batchInterval * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception * @throws E the e */ @SuppressWarnings("rawtypes") public static* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * int importData(final DataSet dataset, final int offset, final int count, final Try.Predicate super Object[], E> filter, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval, final Map columnTypeMap) throws UncheckedSQLException, E { PreparedStatement stmt = null; try { stmt = prepareStatement(conn, insertSQL); return importData(dataset, offset, count, filter, stmt, batchSize, batchInterval, columnTypeMap); } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { JdbcUtil.closeQuietly(stmt); } } /** * Imports the data from DataSet
to database. * * @param dataset * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param stmtSetter * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final Connection conn, final String insertSQL, final JdbcUtil.BiParametersSetter super PreparedStatement, ? super Object[]> stmtSetter) throws UncheckedSQLException { return importData(dataset, 0, dataset.size(), conn, insertSQL, stmtSetter); } /** * Imports the data from* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * DataSet
to database. * * @param dataset * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param stmtSetter * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final int offset, final int count, final Connection conn, final String insertSQL, final JdbcUtil.BiParametersSetter super PreparedStatement, ? super Object[]> stmtSetter) throws UncheckedSQLException { return importData(dataset, offset, count, conn, insertSQL, 200, 0, stmtSetter); } /** * Imports the data from* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * DataSet
to database. * * @param dataset * @param offset * @param count * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: ** @param batchSize * @param batchInterval * @param stmtSetter * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final int offset, final int count, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval, final JdbcUtil.BiParametersSetter super PreparedStatement, ? super Object[]> stmtSetter) throws UncheckedSQLException { return importData(dataset, offset, count, Fn.alwaysTrue(), conn, insertSQL, batchSize, batchInterval, stmtSetter); } /** * Imports the data from* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * DataSet
to database. * * @param* @param dataset * @param offset * @param count * @param filter * @param conn * @param insertSQL the column order in the sql must be consistent with the column order in the DataSet. Here is sample about how to create the sql: * * @param batchSize * @param batchInterval * @param stmtSetter * @return * @throws UncheckedSQLException the unchecked SQL exception * @throws E the e */ public static* List
columnNameList = new ArrayList<>(dataset.columnNameList()); * columnNameList.retainAll(yourSelectColumnNames); * String sql = RE.insert(columnNameList).into(tableName).sql(); * int importData(final DataSet dataset, final int offset, final int count, final Try.Predicate super Object[], E> filter, final Connection conn, final String insertSQL, final int batchSize, final int batchInterval, final JdbcUtil.BiParametersSetter super PreparedStatement, ? super Object[]> stmtSetter) throws UncheckedSQLException, E { PreparedStatement stmt = null; try { stmt = prepareStatement(conn, insertSQL); return importData(dataset, offset, count, filter, stmt, batchSize, batchInterval, stmtSetter); } catch (SQLException e) { throw new UncheckedSQLException(e); } finally { JdbcUtil.closeQuietly(stmt); } } /** * Imports the data from DataSet
to database. * * @param dataset * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final PreparedStatement stmt) throws UncheckedSQLException { return importData(dataset, dataset.columnNameList(), stmt); } /** * Imports the data fromDataSet
to database. * * @param dataset * @param selectColumnNames * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final CollectionselectColumnNames, final PreparedStatement stmt) throws UncheckedSQLException { return importData(dataset, selectColumnNames, 0, dataset.size(), stmt); } /** * Imports the data from DataSet
to database. * * @param dataset * @param selectColumnNames * @param offset * @param count * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final CollectionselectColumnNames, final int offset, final int count, final PreparedStatement stmt) throws UncheckedSQLException { return importData(dataset, selectColumnNames, offset, count, stmt, 200, 0); } /** * Imports the data from DataSet
to database. * * @param dataset * @param selectColumnNames * @param offset * @param count * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param batchSize * @param batchInterval * @return * @throws UncheckedSQLException the unchecked SQL exception */ public static int importData(final DataSet dataset, final CollectionselectColumnNames, final int offset, final int count, final PreparedStatement stmt, final int batchSize, final int batchInterval) throws UncheckedSQLException { return importData(dataset, selectColumnNames, offset, count, Fn.alwaysTrue(), stmt, batchSize, batchInterval); } /** * Imports the data from DataSet
to database. * * @param* @param dataset * @param selectColumnNames * @param offset * @param count * @param filter * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param batchSize * @param batchInterval * @return * @throws UncheckedSQLException the unchecked SQL exception * @throws E the e */ public static int importData(final DataSet dataset, final Collection selectColumnNames, final int offset, final int count, final Try.Predicate super Object[], E> filter, final PreparedStatement stmt, final int batchSize, final int batchInterval) throws UncheckedSQLException, E { final Type> objType = N.typeOf(Object.class); final Map > columnTypeMap = new HashMap<>(); for (String propName : selectColumnNames) { columnTypeMap.put(propName, objType); } return importData(dataset, offset, count, filter, stmt, batchSize, batchInterval, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param dataset * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final PreparedStatement stmt, final MapcolumnTypeMap) throws UncheckedSQLException { return importData(dataset, 0, dataset.size(), stmt, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param dataset * @param offset * @param count * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final int offset, final int count, final PreparedStatement stmt, final MapcolumnTypeMap) throws UncheckedSQLException { return importData(dataset, offset, count, stmt, 200, 0, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param dataset * @param offset * @param count * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param batchSize * @param batchInterval * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final int offset, final int count, final PreparedStatement stmt, final int batchSize, final int batchInterval, final MapcolumnTypeMap) throws UncheckedSQLException { return importData(dataset, offset, count, Fn.alwaysTrue(), stmt, batchSize, batchInterval, columnTypeMap); } /** * Imports the data from DataSet
to database. * * @param* @param dataset * @param offset * @param count * @param filter * @param stmt the column order in the sql must be consistent with the column order in the DataSet. * @param batchSize * @param batchInterval * @param columnTypeMap * @return * @throws UncheckedSQLException the unchecked SQL exception * @throws E the e */ @SuppressWarnings("rawtypes") public static int importData(final DataSet dataset, final int offset, final int count, final Try.Predicate super Object[], E> filter, final PreparedStatement stmt, final int batchSize, final int batchInterval, final Map columnTypeMap) throws UncheckedSQLException, E { N.checkArgument(offset >= 0 && count >= 0, "'offset'=%s and 'count'=%s can't be negative", offset, count); N.checkArgument(batchSize > 0 && batchInterval >= 0, "'batchSize'=%s must be greater than 0 and 'batchInterval'=%s can't be negative", batchSize, batchInterval); int result = 0; try { final int columnCount = columnTypeMap.size(); final List columnNameList = dataset.columnNameList(); final int[] columnIndexes = new int[columnCount]; final Type