@Override public final int[] execute() { // [#1180] Run batch queries with BatchMultiple, if no bind variables // should be used... if (executeStaticStatements(configuration.settings())) { return executeStatic(); } else { return executePrepared(); } }
@Override public Settings settings() { return delegate.settings(); }
@Override public final int execute() { if (isExecutable()) { // Get the attached configuration of this query Configuration c = configuration(); // [#1191] The following triggers a start event on all listeners. // This may be used to provide jOOQ with a JDBC connection, // in case this Query / Configuration was previously // deserialised DefaultExecuteContext ctx = new DefaultExecuteContext(c, this); ExecuteListener listener = new ExecuteListeners(ctx); int result = 0; try { // [#385] If a statement was previously kept open if (keepStatement() && statement != null) { ctx.sql(rendered.sql); ctx.statement(statement); // [#3191] Pre-initialise the ExecuteContext with a previous connection, if available. ctx.connection(c.connectionProvider(), statement.getConnection()); } // [#385] First time statement preparing else { listener.renderStart(ctx); rendered = getSQL0(ctx); ctx.sql(rendered.sql); listener.renderEnd(ctx); rendered.sql = ctx.sql(); // [#3234] Defer initialising of a connection until the prepare step // This optimises unnecessary ConnectionProvider.acquire() calls when // ControlFlowSignals are thrown if (ctx.connection() == null) { throw new DetachedException("Cannot execute query. No Connection configured"); } listener.prepareStart(ctx); prepare(ctx); listener.prepareEnd(ctx); statement = ctx.statement(); } // [#1856] [#4753] Set the query timeout onto the Statement int t = SettingsTools.getQueryTimeout(timeout, ctx.settings()); if (t != 0) { ctx.statement().setQueryTimeout(t); } if ( // [#1145] Bind variables only for true prepared statements // [#2414] Even if parameters are inlined here, child // QueryParts may override this behaviour! executePreparedStatements(c.settings()) && // [#1520] Renderers may enforce static statements, too !Boolean.TRUE.equals(ctx.data(DATA_FORCE_STATIC_STATEMENT))) { listener.bindStart(ctx); if (rendered.bindValues != null) using(c).bindContext(ctx.statement()).visit(rendered.bindValues); listener.bindEnd(ctx); } result = execute(ctx, listener); return result; } // [#3427] ControlFlowSignals must not be passed on to ExecuteListners catch (ControlFlowSignal e) { throw e; } catch (RuntimeException e) { ctx.exception(e); listener.exception(ctx); throw ctx.exception(); } catch (SQLException e) { ctx.sqlException(e); listener.exception(ctx); throw ctx.exception(); } finally { // [#2385] Successful fetchLazy() needs to keep open resources if (!keepResultSet() || ctx.exception() != null) { Tools.safeClose(listener, ctx, keepStatement()); } if (!keepStatement()) { statement = null; rendered = null; } } } else { if (log.isDebugEnabled()) log.debug("Query is not executable", this); return 0; } }
private final int[] executePrepared() { Map<String, List<Query>> queries = new LinkedHashMap<String, List<Query>>(); QueryCollector collector = new QueryCollector(); // Add the QueryCollector to intercept query execution after rendering Configuration local = configuration.derive( Utils.combine( configuration.executeListenerProviders(), new DefaultExecuteListenerProvider(collector))); // [#1537] Communicate with UpdatableRecordImpl local.data(Utils.DATA_OMIT_RETURNING_CLAUSE, true); // [#1529] Avoid DEBUG logging of single INSERT / UPDATE statements local.settings().setExecuteLogging(false); for (int i = 0; i < records.length; i++) { Configuration previous = ((AttachableInternal) records[i]).configuration(); try { records[i].attach(local); executeAction(i); } catch (QueryCollectorSignal e) { Query query = e.getQuery(); String sql = e.getSQL(); // Aggregate executable queries by identical SQL if (query.isExecutable()) { List<Query> list = queries.get(sql); if (list == null) { list = new ArrayList<Query>(); queries.put(sql, list); } list.add(query); } } finally { records[i].attach(previous); } } // Execute one batch statement for each identical SQL statement. Every // SQL statement may have several queries with different bind values. // The order is preserved as much as possible List<Integer> result = new ArrayList<Integer>(); for (Entry<String, List<Query>> entry : queries.entrySet()) { BatchBindStep batch = create.batch(entry.getValue().get(0)); for (Query query : entry.getValue()) { batch.bind(query.getBindValues().toArray()); } int[] array = batch.execute(); for (int i : array) { result.add(i); } } int[] array = new int[result.size()]; for (int i = 0; i < result.size(); i++) { array[i] = result.get(i); } updateChangedFlag(); return array; }
@Override public final int execute() { if (isExecutable()) { // Get the attached configuration of this query Configuration c = configuration(); // [#1191] The following triggers a start event on all listeners. // This may be used to provide jOOQ with a JDBC connection, // in case this Query / Configuration was previously // deserialised ExecuteContext ctx = new DefaultExecuteContext(c, this); ExecuteListener listener = new ExecuteListeners(ctx); int result = 0; try { if (ctx.connection() == null) { throw new DetachedException("Cannot execute query. No Connection configured"); } // [#385] If a statement was previously kept open if (keepStatement() && statement != null) { ctx.sql(sql); ctx.statement(statement); } // [#385] First time statement preparing else { listener.renderStart(ctx); ctx.sql(getSQL0(ctx)); listener.renderEnd(ctx); sql = ctx.sql(); listener.prepareStart(ctx); prepare(ctx); listener.prepareEnd(ctx); statement = ctx.statement(); } // [#1856] Set the query timeout onto the Statement if (timeout != 0) { ctx.statement().setQueryTimeout(timeout); } if ( // [#1145] Bind variables only for true prepared statements // [#2414] Even if parameters are inlined here, child // QueryParts may override this behaviour! executePreparedStatements(c.settings()) && // [#1520] Renderers may enforce static statements, too !Boolean.TRUE.equals(ctx.data(DATA_FORCE_STATIC_STATEMENT))) { listener.bindStart(ctx); using(c).bindContext(ctx.statement()).visit(this); listener.bindEnd(ctx); } result = execute(ctx, listener); return result; } catch (SQLException e) { ctx.sqlException(e); listener.exception(ctx); throw ctx.exception(); } finally { // [#2385] Successful fetchLazy() needs to keep open resources if (!keepResultSet() || ctx.exception() != null) { Utils.safeClose(listener, ctx, keepStatement()); } if (!keepStatement()) { statement = null; sql = null; } } } else { if (log.isDebugEnabled()) { log.debug("Query is not executable", this); } return 0; } }