provide(CacheContext context);
}
diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java
index a9977dd258..9f91165989 100644
--- a/jOOQ/src/main/java/org/jooq/DSLContext.java
+++ b/jOOQ/src/main/java/org/jooq/DSLContext.java
@@ -103,6 +103,7 @@ import org.jooq.exception.InvalidResultException;
import org.jooq.exception.MappingException;
import org.jooq.exception.NoDataFoundException;
import org.jooq.exception.TooManyRowsException;
+import org.jooq.impl.CacheType;
import org.jooq.impl.DSL;
import org.jooq.impl.ParserException;
import org.jooq.impl.ThreadLocalTransactionProvider;
@@ -195,9 +196,23 @@ public interface DSLContext extends Scope {
* A JDBC connection that runs each statement through the {@link #parser()}
* first, prior to re-generating and running the SQL.
*
+ * Static statements are translated eagerly upon execution, e.g. of
+ * {@link java.sql.Statement#executeQuery(String)}. Prepared statements are
+ * prepared lazily once all bind variables are available, because the
+ * specific bind value and type may influence the generated SQL. As such, a
+ * {@link PreparedStatement} created from a parsing connection does not yet
+ * allocate any server side resources until it is executed for the first
+ * time.
+ *
+ * The {@link Configuration#cacheProvider()} is called for
+ * {@link CacheType#CACHE_PARSING_CONNECTION} to provide a translation cache
+ * to avoid the overhead of re-parsing and re-generating the same SQL string
+ * all the time. By default, this is an LRU cache.
+ *
* The resulting {@link Connection} wraps an underlying JDBC connection that
* has been obtained from {@link ConnectionProvider#acquire()} and must be
- * released by calling {@link Connection#close()}.
+ * released by calling {@link Connection#close()}, which calls
+ * {@link ConnectionProvider#release(Connection)}.
*/
@NotNull
Connection parsingConnection();
diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java
index 9673bd32ab..0de0de62cb 100644
--- a/jOOQ/src/main/java/org/jooq/conf/Settings.java
+++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java
@@ -174,6 +174,10 @@ public class Settings
@XmlElement(defaultValue = "true")
protected Boolean cacheRecordMappers = true;
@XmlElement(defaultValue = "true")
+ protected Boolean cacheParsingConnection = true;
+ @XmlElement(defaultValue = "8192")
+ protected Integer cacheParsingConnectionLRUCacheSize = 8192;
+ @XmlElement(defaultValue = "true")
protected Boolean cachePreparedStatementInLoader = true;
@XmlElement(defaultValue = "THROW_ALL")
@XmlSchemaType(name = "string")
@@ -1544,6 +1548,46 @@ public class Settings
this.cacheRecordMappers = value;
}
+ /**
+ * Whether parsing connection translations should be cached in the configuration.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isCacheParsingConnection() {
+ return cacheParsingConnection;
+ }
+
+ /**
+ * Sets the value of the cacheParsingConnection property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setCacheParsingConnection(Boolean value) {
+ this.cacheParsingConnection = value;
+ }
+
+ /**
+ * The default implementation of the ParsingConnection cache's LRU cache size.
+ *
+ */
+ public Integer getCacheParsingConnectionLRUCacheSize() {
+ return cacheParsingConnectionLRUCacheSize;
+ }
+
+ /**
+ * The default implementation of the ParsingConnection cache's LRU cache size.
+ *
+ */
+ public void setCacheParsingConnectionLRUCacheSize(Integer value) {
+ this.cacheParsingConnectionLRUCacheSize = value;
+ }
+
/**
* Whether JDBC {@link java.sql.PreparedStatement} instances should be cached in loader API.
*
@@ -2986,6 +3030,20 @@ public class Settings
return this;
}
+ public Settings withCacheParsingConnection(Boolean value) {
+ setCacheParsingConnection(value);
+ return this;
+ }
+
+ /**
+ * The default implementation of the ParsingConnection cache's LRU cache size.
+ *
+ */
+ public Settings withCacheParsingConnectionLRUCacheSize(Integer value) {
+ setCacheParsingConnectionLRUCacheSize(value);
+ return this;
+ }
+
public Settings withCachePreparedStatementInLoader(Boolean value) {
setCachePreparedStatementInLoader(value);
return this;
@@ -3437,6 +3495,8 @@ public class Settings
builder.append("updatablePrimaryKeys", updatablePrimaryKeys);
builder.append("reflectionCaching", reflectionCaching);
builder.append("cacheRecordMappers", cacheRecordMappers);
+ builder.append("cacheParsingConnection", cacheParsingConnection);
+ builder.append("cacheParsingConnectionLRUCacheSize", cacheParsingConnectionLRUCacheSize);
builder.append("cachePreparedStatementInLoader", cachePreparedStatementInLoader);
builder.append("throwExceptions", throwExceptions);
builder.append("fetchWarnings", fetchWarnings);
@@ -4003,6 +4063,24 @@ public class Settings
return false;
}
}
+ if (cacheParsingConnection == null) {
+ if (other.cacheParsingConnection!= null) {
+ return false;
+ }
+ } else {
+ if (!cacheParsingConnection.equals(other.cacheParsingConnection)) {
+ return false;
+ }
+ }
+ if (cacheParsingConnectionLRUCacheSize == null) {
+ if (other.cacheParsingConnectionLRUCacheSize!= null) {
+ return false;
+ }
+ } else {
+ if (!cacheParsingConnectionLRUCacheSize.equals(other.cacheParsingConnectionLRUCacheSize)) {
+ return false;
+ }
+ }
if (cachePreparedStatementInLoader == null) {
if (other.cachePreparedStatementInLoader!= null) {
return false;
@@ -4515,6 +4593,8 @@ public class Settings
result = ((prime*result)+((updatablePrimaryKeys == null)? 0 :updatablePrimaryKeys.hashCode()));
result = ((prime*result)+((reflectionCaching == null)? 0 :reflectionCaching.hashCode()));
result = ((prime*result)+((cacheRecordMappers == null)? 0 :cacheRecordMappers.hashCode()));
+ result = ((prime*result)+((cacheParsingConnection == null)? 0 :cacheParsingConnection.hashCode()));
+ result = ((prime*result)+((cacheParsingConnectionLRUCacheSize == null)? 0 :cacheParsingConnectionLRUCacheSize.hashCode()));
result = ((prime*result)+((cachePreparedStatementInLoader == null)? 0 :cachePreparedStatementInLoader.hashCode()));
result = ((prime*result)+((throwExceptions == null)? 0 :throwExceptions.hashCode()));
result = ((prime*result)+((fetchWarnings == null)? 0 :fetchWarnings.hashCode()));
diff --git a/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java b/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java
index 9ef505658b..93cec23740 100644
--- a/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java
+++ b/jOOQ/src/main/java/org/jooq/conf/SettingsTools.java
@@ -164,12 +164,26 @@ public final class SettingsTools {
}
/**
- * Whether primary keys should be updatable.
+ * Whether reflection caching is active.
*/
public static final boolean reflectionCaching(Settings settings) {
return defaultIfNull(settings.isReflectionCaching(), true);
}
+ /**
+ * Whether record mapper caching is active.
+ */
+ public static final boolean recordMapperCaching(Settings settings) {
+ return defaultIfNull(settings.isCacheRecordMappers(), true);
+ }
+
+ /**
+ * Whether parsing connection caching is active.
+ */
+ public static final boolean parsingConnectionCaching(Settings settings) {
+ return defaultIfNull(settings.isCacheParsingConnection(), true);
+ }
+
/**
* The render locale that is applicable, or the default locale if no such
* locale is configured.
diff --git a/jOOQ/src/main/java/org/jooq/impl/CacheType.java b/jOOQ/src/main/java/org/jooq/impl/CacheType.java
index ebcc02d6d3..f010cdc35c 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CacheType.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CacheType.java
@@ -38,11 +38,19 @@
package org.jooq.impl;
+import static org.jooq.impl.CacheType.CacheCategory.PARSING_CONNECTION;
+import static org.jooq.impl.CacheType.CacheCategory.RECORD_MAPPER;
+import static org.jooq.impl.CacheType.CacheCategory.REFLECTION;
+
+import java.util.function.Predicate;
+
import org.jooq.CacheProvider;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.RecordMapper;
import org.jooq.RecordType;
+import org.jooq.conf.Settings;
+import org.jooq.conf.SettingsTools;
/**
* The set of internal cache types.
@@ -64,60 +72,74 @@ public enum CacheType {
* A reflection cache for lookups of JPA annotated getters in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_ANNOTATED_GETTER("org.jooq.configuration.reflection-cache.get-annotated-getter"),
+ REFLECTION_CACHE_GET_ANNOTATED_GETTER(REFLECTION, "org.jooq.configuration.reflection-cache.get-annotated-getter"),
/**
* A reflection cache for lookups of JPA annotated members in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_ANNOTATED_MEMBERS("org.jooq.configuration.reflection-cache.get-annotated-members"),
+ REFLECTION_CACHE_GET_ANNOTATED_MEMBERS(REFLECTION, "org.jooq.configuration.reflection-cache.get-annotated-members"),
/**
* A reflection cache for lookups of JPA annotated setters in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_ANNOTATED_SETTERS("org.jooq.configuration.reflection-cache.get-annotated-setters"),
+ REFLECTION_CACHE_GET_ANNOTATED_SETTERS(REFLECTION, "org.jooq.configuration.reflection-cache.get-annotated-setters"),
/**
* A reflection cache for lookups of getters matched by name in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_MATCHING_GETTER("org.jooq.configuration.reflection-cache.get-matching-getter"),
+ REFLECTION_CACHE_GET_MATCHING_GETTER(REFLECTION, "org.jooq.configuration.reflection-cache.get-matching-getter"),
/**
* A reflection cache for lookups of members matched by name in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_MATCHING_MEMBERS("org.jooq.configuration.reflection-cache.get-matching-members"),
+ REFLECTION_CACHE_GET_MATCHING_MEMBERS(REFLECTION, "org.jooq.configuration.reflection-cache.get-matching-members"),
/**
* A reflection cache for lookups of setters matched by name in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_GET_MATCHING_SETTERS("org.jooq.configuration.reflection-cache.get-matching-setters"),
+ REFLECTION_CACHE_GET_MATCHING_SETTERS(REFLECTION, "org.jooq.configuration.reflection-cache.get-matching-setters"),
/**
* A reflection cache to check if a type has any JPA annotations at all, in
* {@link DefaultRecordMapper}.
*/
- REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS("org.jooq.configuration.reflection-cache.has-column-annotations"),
+ REFLECTION_CACHE_HAS_COLUMN_ANNOTATIONS(REFLECTION, "org.jooq.configuration.reflection-cache.has-column-annotations"),
/**
* A cache used by the {@link DefaultRecordMapperProvider} to cache all
* {@link RecordMapper} instances and their possibly expensive
* initialisations per {@link RecordType} and {@link Class} pairs.
*/
- CACHE_RECORD_MAPPERS("org.jooq.configuration.cache.record-mappers"),
+ CACHE_RECORD_MAPPERS(RECORD_MAPPER, "org.jooq.configuration.cache.record-mappers"),
/**
* [#8334] A cache for SQL to SQL translations in the
* {@link DSLContext#parsingConnection()}, to speed up its usage.
*/
- CACHE_PARSING_CONNECTION("org.jooq.configuration.cache.parsing-connection");
+ CACHE_PARSING_CONNECTION(PARSING_CONNECTION, "org.jooq.configuration.cache.parsing-connection");
- final String key;
+ final CacheCategory category;
+ final String key;
- CacheType(String key) {
+ CacheType(CacheCategory category, String key) {
+ this.category = category;
this.key = key;
}
+
+ enum CacheCategory {
+ REFLECTION(SettingsTools::reflectionCaching),
+ RECORD_MAPPER(SettingsTools::recordMapperCaching),
+ PARSING_CONNECTION(SettingsTools::parsingConnectionCaching);
+
+ final Predicate super Settings> predicate;
+
+ CacheCategory(Predicate super Settings> predicate) {
+ this.predicate = predicate;
+ }
+ }
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java
index 37f82488ab..709c008e07 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DSL.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java
@@ -407,7 +407,6 @@ import org.jooq.XMLAttributes;
import org.jooq.XMLExistsPassingStep;
import org.jooq.XMLQueryPassingStep;
import org.jooq.XMLTablePassingStep;
-import org.jooq.conf.ParamType;
import org.jooq.conf.Settings;
import org.jooq.exception.SQLDialectNotSupportedException;
import org.jooq.impl.XMLParse.DocumentOrContent;
diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java
new file mode 100644
index 0000000000..32d29c52e2
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheContext.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq.impl;
+
+import org.jooq.CacheContext;
+import org.jooq.Configuration;
+
+/**
+ * @author Lukas Eder
+ */
+final class DefaultCacheContext extends AbstractScope implements CacheContext {
+
+ private final CacheType cacheType;
+
+ DefaultCacheContext(Configuration configuration, CacheType cacheType) {
+ super(configuration);
+
+ this.cacheType = cacheType;
+ }
+
+ @Override
+ public final CacheType cacheType() {
+ return cacheType;
+ }
+}
diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultCacheProvider.java b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheProvider.java
index a37bb1d7a3..e18111a2a3 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DefaultCacheProvider.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DefaultCacheProvider.java
@@ -38,10 +38,13 @@
package org.jooq.impl;
import static java.util.Collections.synchronizedMap;
+import static org.jooq.impl.Tools.settings;
+import static org.jooq.tools.StringUtils.defaultIfNull;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.jooq.CacheContext;
import org.jooq.CacheProvider;
/**
@@ -53,13 +56,13 @@ import org.jooq.CacheProvider;
final class DefaultCacheProvider implements CacheProvider {
@Override
- public Map provide(CacheType key) {
- switch (key) {
+ public Map provide(CacheContext ctx) {
+ switch (ctx.cacheType()) {
// TODO: Is there a better implementation than wrapping LinkedHashMap
// in synchronizedMap(), i.e. one that does not use a monitor?
case CACHE_PARSING_CONNECTION:
- return synchronizedMap(new LRUCache<>(1024));
+ return synchronizedMap(new LRUCache<>(defaultIfNull(settings(ctx.configuration()).getCacheParsingConnectionLRUCacheSize(), 8912)));
default:
return new ConcurrentHashMap<>();
diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java
index 72bb188697..761aa7cfcb 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Tools.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java
@@ -3338,7 +3338,7 @@ final class Tools {
configuration = new DefaultConfiguration();
// Shortcut caching when the relevant Settings flag isn't set.
- if (!reflectionCaching(configuration.settings()))
+ if (!type.category.predicate.test(configuration.settings()))
return operation.get();
Object cacheOrNull = configuration.data(type);
@@ -3347,7 +3347,10 @@ final class Tools {
cacheOrNull = configuration.data(type);
if (cacheOrNull == null)
- configuration.data(type, cacheOrNull = defaultIfNull(configuration.cacheProvider().provide(type), NULL));
+ configuration.data(type, cacheOrNull = defaultIfNull(
+ configuration.cacheProvider().provide(new DefaultCacheContext(configuration, type)),
+ NULL
+ ));
}
}
diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd
index 9407899197..61f5bead80 100644
--- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd
+++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.15.0.xsd
@@ -387,6 +387,14 @@ UpdatableRecord.store() and UpdatableRecord.update().]]>
+
+
+
+
+
+
+
+