diff --git a/src/main/asciidoc/user-guide.adoc b/src/main/asciidoc/user-guide.adoc
index 9aa9423..26d02b9 100644
--- a/src/main/asciidoc/user-guide.adoc
+++ b/src/main/asciidoc/user-guide.adoc
@@ -1124,7 +1124,7 @@ The mybatis-thymeleaf provides following properties for customizing configuratio
|`String[]`
|`"*.sql"`
-4+|*Template file path provider configuration(TemplateFilePathProvider)*
+4+|*Template file path provider configuration(for TemplateFilePathProvider)*
|`template-file.path-provider.prefix`
|The prefix for adding to template file path
@@ -1146,6 +1146,11 @@ The mybatis-thymeleaf provides following properties for customizing configuratio
|`Boolean`
|`true` (includes mapper name)
+|`template-file.path-provider.cache-enabled`
+|Whether cache a resolved template file path
+|`Boolean`
+|`true` (cache a resolved template file path)
+
4+|*Dialect configuration*
|`dialect.prefix`
diff --git a/src/main/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverConfig.java b/src/main/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverConfig.java
index a2c3ade..2d98718 100644
--- a/src/main/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverConfig.java
+++ b/src/main/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverConfig.java
@@ -331,6 +331,11 @@ public static class PathProviderConfig {
*/
private boolean includesMapperNameWhenSeparateDirectory = true;
+ /**
+ * Whether cache a resolved template file path.
+ */
+ private boolean cacheEnabled = true;
+
/**
* Get a prefix for adding to template file path.
*
@@ -403,7 +408,7 @@ public void setSeparateDirectoryPerMapper(boolean separateDirectoryPerMapper) {
* Default is {@code true}.
*
*
- * @return If includes mapper name, set {@code true}
+ * @return If includes mapper name, return {@code true}
*/
public boolean isIncludesMapperNameWhenSeparateDirectory() {
return includesMapperNameWhenSeparateDirectory;
@@ -422,6 +427,28 @@ public void setIncludesMapperNameWhenSeparateDirectory(boolean includesMapperNam
this.includesMapperNameWhenSeparateDirectory = includesMapperNameWhenSeparateDirectory;
}
+ /**
+ * Get whether cache a resolved template file path.
+ *
+ * Default is {@code true}.
+ *
+ *
+ * @return If cache a resolved template file path, return {@code true}
+ */
+ public boolean isCacheEnabled() {
+ return cacheEnabled;
+ }
+
+ /**
+ * Set whether cache a resolved template file path.
+ *
+ * @param cacheEnabled
+ * If want to cache, set {@code true}
+ */
+ public void setCacheEnabled(boolean cacheEnabled) {
+ this.cacheEnabled = cacheEnabled;
+ }
+
}
}
@@ -600,7 +627,6 @@ public void setLikeAdditionalEscapeTargetChars(Character... likeAdditionalEscape
* {@code "*.sql"} |
*
*
- *
* Template file path provider configuration(TemplateFilePathProvider) |
*
*
@@ -609,24 +635,26 @@ public void setLikeAdditionalEscapeTargetChars(Character... likeAdditionalEscape
* {@code ""} |
*
*
- *
* template-file.path-provider.includes-package-path |
* Whether includes package path part |
* {@code true} |
*
*
- *
- * template-file.patterns |
+ * template-file.path-provider.separate-directory-per-mapper |
* Whether separate directory per mapper |
* {@code true} |
*
*
- *
- * template-file.patterns |
+ * template-file.path-provider.includes-mapper-name-when-separate-directory |
* Whether includes mapper name into file name when separate directory per mapper |
* {@code true} |
*
*
+ * template-file.path-provider.cache-enabled |
+ * Whether cache a resolved template file path |
+ * {@code true} |
+ *
+ *
* Dialect configuration |
*
*
diff --git a/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java b/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java
index 3058f40..09be7f2 100644
--- a/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java
+++ b/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java
@@ -18,6 +18,8 @@
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.io.Resources;
@@ -75,6 +77,8 @@ public class TemplateFilePathProvider {
private static PathGenerator pathGenerator = DEFAULT_PATH_GENERATOR;
private static ThymeleafLanguageDriverConfig languageDriverConfig = DEFAULT_LANGUAGE_DRIVER_CONFIG;
+ private static ConcurrentMap cache = new ConcurrentHashMap<>();
+
/**
* Set custom implementation for {@link PathGenerator}.
*
@@ -124,7 +128,16 @@ public static void setLanguageDriverConfig(ThymeleafLanguageDriverConfig languag
* @return an SQL scripting string(template file path)
*/
public static String provideSql(ProviderContext context) {
- return providePath(context.getMapperType(), context.getMapperMethod(), context.getDatabaseId());
+ return languageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled()
+ ? cache.computeIfAbsent(context, c -> providePath(c.getMapperType(), c.getMapperMethod(), c.getDatabaseId()))
+ : providePath(context.getMapperType(), context.getMapperMethod(), context.getDatabaseId());
+ }
+
+ /**
+ * Clear cache.
+ */
+ public static void clearCache() {
+ cache.clear();
}
static String providePath(Class> mapperType, Method mapperMethod, String databaseId) {
@@ -183,7 +196,6 @@ private static String generateTemplatePath(Class> type, Method method, String
path.append('-').append(databaseId);
}
path.append(".sql");
- System.out.println(path);
return path.toString();
}
diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverTest.java b/src/test/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverTest.java
index 4403184..7b88b9a 100644
--- a/src/test/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverTest.java
+++ b/src/test/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverTest.java
@@ -227,6 +227,7 @@ void testCustomWithCustomConfigFileUsingMethodArgument() {
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
Assertions.assertFalse(
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
+ Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
}
@@ -245,6 +246,7 @@ void testCustomWithCustomizerFunction() {
c.getTemplateFile().getPathProvider().setIncludesPackagePath(false);
c.getTemplateFile().getPathProvider().setSeparateDirectoryPerMapper(false);
c.getTemplateFile().getPathProvider().setIncludesMapperNameWhenSeparateDirectory(false);
+ c.getTemplateFile().getPathProvider().setCacheEnabled(false);
c.getDialect().setPrefix("mbs");
c.getDialect().setLikeEscapeChar('~');
c.getDialect().setLikeEscapeClauseFormat("escape '%s'");
@@ -289,6 +291,7 @@ void testCustomWithCustomizerFunction() {
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
Assertions.assertFalse(
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
+ Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
}
@Test
@@ -307,6 +310,7 @@ void testCustomWithBuilderUsingCustomProperties() {
customProperties.setProperty("template-file.path-provider.includes-package-path", "false");
customProperties.setProperty("template-file.path-provider.separate-directory-per-mapper", "false");
customProperties.setProperty("template-file.path-provider.includes-mapper-name-when-separate-directory", "false");
+ customProperties.setProperty("template-file.path-provider.cache-enabled", "false");
customProperties.setProperty("dialect.prefix", "mbs");
customProperties.setProperty("dialect.like-escape-char", "~");
customProperties.setProperty("dialect.like-escape-clause-format", "escape '%s'");
@@ -353,6 +357,7 @@ void testCustomWithBuilderUsingCustomProperties() {
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
Assertions.assertFalse(
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
+ Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
}
@Test
diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperNoCacheTest.java b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperNoCacheTest.java
new file mode 100644
index 0000000..64361d0
--- /dev/null
+++ b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperNoCacheTest.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2018-2019 the original author or authors.
+ *
+ * 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 org.mybatis.scripting.thymeleaf.integrationtest;
+
+import java.io.Reader;
+import java.sql.Connection;
+
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.jdbc.ScriptRunner;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.hsqldb.jdbc.JDBCDataSource;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriver;
+import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig;
+import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name;
+import org.mybatis.scripting.thymeleaf.integrationtest.mapper.TemplateFilePathProviderMapper;
+
+@DisabledIfSystemProperty(named = "mybatis.version", matches = "3\\.4\\..*|3\\.5\\.0")
+class TemplateFilePathProviderMapperNoCacheTest {
+ private static SqlSessionFactory sqlSessionFactory;
+
+ @BeforeAll
+ static void setUp() throws Exception {
+ Class.forName("org.hsqldb.jdbcDriver");
+ JDBCDataSource dataSource = new JDBCDataSource();
+ dataSource.setUrl("jdbc:hsqldb:mem:db1");
+ dataSource.setUser("sa");
+ dataSource.setPassword("");
+
+ try (Connection conn = dataSource.getConnection()) {
+ try (Reader reader = Resources.getResourceAsReader("create-db.sql")) {
+ ScriptRunner runner = new ScriptRunner(conn);
+ runner.setLogWriter(null);
+ runner.setErrorLogWriter(null);
+ runner.runScript(reader);
+ conn.commit();
+ }
+ }
+
+ TransactionFactory transactionFactory = new JdbcTransactionFactory();
+ Environment environment = new Environment("development", transactionFactory, dataSource);
+
+ Configuration configuration = new Configuration(environment);
+ configuration.setMapUnderscoreToCamelCase(true);
+ configuration.getLanguageRegistry()
+ .register(new ThymeleafLanguageDriver(ThymeleafLanguageDriverConfig.newInstance(c -> {
+ c.getTemplateFile().getPathProvider().setPrefix("sql/");
+ c.getTemplateFile().getPathProvider().setIncludesPackagePath(false);
+ c.getTemplateFile().getPathProvider().setCacheEnabled(false);
+ })));
+ configuration.setDefaultScriptingLanguage(ThymeleafLanguageDriver.class);
+
+ configuration.addMapper(TemplateFilePathProviderMapper.class);
+ sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
+ }
+
+ @Test
+ void testInsert() {
+ try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
+ TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
+ Name name = new Name();
+ name.setFirstName("Thymeleaf");
+ name.setLastName("MyBatis");
+ mapper.insert(name);
+
+ Name loadedName = mapper.findById(name.getId());
+ Assertions.assertEquals(name.getFirstName(), loadedName.getFirstName());
+ Assertions.assertEquals(name.getLastName(), loadedName.getLastName());
+ }
+ }
+
+ @Test
+ void testUpdate() {
+ try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
+ TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
+ Name name = new Name();
+ name.setFirstName("Thymeleaf");
+ name.setLastName("MyBatis");
+ mapper.insert(name);
+
+ Name updatingName = new Name();
+ updatingName.setId(name.getId());
+ updatingName.setFirstName("Thymeleaf3");
+ mapper.update(updatingName);
+
+ Name loadedName = mapper.findById(name.getId());
+ Assertions.assertEquals(updatingName.getFirstName(), loadedName.getFirstName());
+ Assertions.assertEquals(name.getLastName(), loadedName.getLastName());
+ }
+ }
+
+ @Test
+ void testDelete() {
+ try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
+ TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
+ Name name = new Name();
+ name.setFirstName("Thymeleaf");
+ name.setLastName("MyBatis");
+ mapper.insert(name);
+
+ mapper.delete(name);
+
+ Name loadedName = mapper.findById(name.getId());
+ Assertions.assertNull(loadedName);
+ }
+ }
+
+}
diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java
index 603fd26..3001c4c 100644
--- a/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java
+++ b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java
@@ -28,6 +28,7 @@
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.hsqldb.jdbc.JDBCDataSource;
+import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -36,11 +37,18 @@
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig;
import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name;
import org.mybatis.scripting.thymeleaf.integrationtest.mapper.TemplateFilePathProviderMapper;
+import org.mybatis.scripting.thymeleaf.support.TemplateFilePathProvider;
@DisabledIfSystemProperty(named = "mybatis.version", matches = "3\\.4\\..*|3\\.5\\.0")
class TemplateFilePathProviderMapperTest {
private static SqlSessionFactory sqlSessionFactory;
+ @BeforeAll
+ @AfterAll
+ static void cleanup() {
+ TemplateFilePathProvider.clearCache();
+ }
+
@BeforeAll
static void setUp() throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
diff --git a/src/test/resources/mybatis-thymeleaf-custom.properties b/src/test/resources/mybatis-thymeleaf-custom.properties
index a5beefe..8feb648 100644
--- a/src/test/resources/mybatis-thymeleaf-custom.properties
+++ b/src/test/resources/mybatis-thymeleaf-custom.properties
@@ -25,6 +25,7 @@ template-file.path-provider.prefix=sqls/
template-file.path-provider.includes-package-path=false
template-file.path-provider.separate-directory-per-mapper=false
template-file.path-provider.includes-mapper-name-when-separate-directory=false
+template-file.path-provider.cache-enabled=false
dialect.prefix=mybatis
dialect.like-escape-char=~
dialect.like-escape-clause-format=escape '%s'