Skip to content

Commit a1ed1b7

Browse files
authored
Merge pull request #21 from kazuki43zoo/gh-10-cache
Support cache feature on TemplateFilePathProvider
2 parents 730983a + 1eb7c7f commit a1ed1b7

File tree

7 files changed

+199
-10
lines changed

7 files changed

+199
-10
lines changed

src/main/asciidoc/user-guide.adoc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ The mybatis-thymeleaf provides following properties for customizing configuratio
11241124
|`String[]`
11251125
|`"*.sql"`
11261126

1127-
4+|*Template file path provider configuration(TemplateFilePathProvider)*
1127+
4+|*Template file path provider configuration(for TemplateFilePathProvider)*
11281128

11291129
|`template-file.path-provider.prefix`
11301130
|The prefix for adding to template file path
@@ -1146,6 +1146,11 @@ The mybatis-thymeleaf provides following properties for customizing configuratio
11461146
|`Boolean`
11471147
|`true` (includes mapper name)
11481148

1149+
|`template-file.path-provider.cache-enabled`
1150+
|Whether cache a resolved template file path
1151+
|`Boolean`
1152+
|`true` (cache a resolved template file path)
1153+
11491154
4+|*Dialect configuration*
11501155

11511156
|`dialect.prefix`

src/main/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverConfig.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ public static class PathProviderConfig {
331331
*/
332332
private boolean includesMapperNameWhenSeparateDirectory = true;
333333

334+
/**
335+
* Whether cache a resolved template file path.
336+
*/
337+
private boolean cacheEnabled = true;
338+
334339
/**
335340
* Get a prefix for adding to template file path.
336341
* <p>
@@ -403,7 +408,7 @@ public void setSeparateDirectoryPerMapper(boolean separateDirectoryPerMapper) {
403408
* Default is {@code true}.
404409
* </p>
405410
*
406-
* @return If includes mapper name, set {@code true}
411+
* @return If includes mapper name, return {@code true}
407412
*/
408413
public boolean isIncludesMapperNameWhenSeparateDirectory() {
409414
return includesMapperNameWhenSeparateDirectory;
@@ -422,6 +427,28 @@ public void setIncludesMapperNameWhenSeparateDirectory(boolean includesMapperNam
422427
this.includesMapperNameWhenSeparateDirectory = includesMapperNameWhenSeparateDirectory;
423428
}
424429

430+
/**
431+
* Get whether cache a resolved template file path.
432+
* <p>
433+
* Default is {@code true}.
434+
* </p>
435+
*
436+
* @return If cache a resolved template file path, return {@code true}
437+
*/
438+
public boolean isCacheEnabled() {
439+
return cacheEnabled;
440+
}
441+
442+
/**
443+
* Set whether cache a resolved template file path.
444+
*
445+
* @param cacheEnabled
446+
* If want to cache, set {@code true}
447+
*/
448+
public void setCacheEnabled(boolean cacheEnabled) {
449+
this.cacheEnabled = cacheEnabled;
450+
}
451+
425452
}
426453

427454
}
@@ -600,7 +627,6 @@ public void setLikeAdditionalEscapeTargetChars(Character... likeAdditionalEscape
600627
* <td>{@code "*.sql"}</td>
601628
* </tr>
602629
* <tr>
603-
* <tr>
604630
* <th colspan="3">Template file path provider configuration(TemplateFilePathProvider)</th>
605631
* </tr>
606632
* <tr>
@@ -609,24 +635,26 @@ public void setLikeAdditionalEscapeTargetChars(Character... likeAdditionalEscape
609635
* <td>{@code ""}</td>
610636
* </tr>
611637
* <tr>
612-
* <tr>
613638
* <td>template-file.path-provider.includes-package-path</td>
614639
* <td>Whether includes package path part</td>
615640
* <td>{@code true}</td>
616641
* </tr>
617642
* <tr>
618-
* <tr>
619-
* <td>template-file.patterns</td>
643+
* <td>template-file.path-provider.separate-directory-per-mapper</td>
620644
* <td>Whether separate directory per mapper</td>
621645
* <td>{@code true}</td>
622646
* </tr>
623647
* <tr>
624-
* <tr>
625-
* <td>template-file.patterns</td>
648+
* <td>template-file.path-provider.includes-mapper-name-when-separate-directory</td>
626649
* <td>Whether includes mapper name into file name when separate directory per mapper</td>
627650
* <td>{@code true}</td>
628651
* </tr>
629652
* <tr>
653+
* <td>template-file.path-provider.cache-enabled</td>
654+
* <td>Whether cache a resolved template file path</td>
655+
* <td>{@code true}</td>
656+
* </tr>
657+
* <tr>
630658
* <th colspan="3">Dialect configuration</th>
631659
* </tr>
632660
* <tr>

src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.io.IOException;
1919
import java.lang.reflect.Method;
2020
import java.util.Optional;
21+
import java.util.concurrent.ConcurrentHashMap;
22+
import java.util.concurrent.ConcurrentMap;
2123

2224
import org.apache.ibatis.builder.annotation.ProviderContext;
2325
import org.apache.ibatis.io.Resources;
@@ -75,6 +77,8 @@ public class TemplateFilePathProvider {
7577
private static PathGenerator pathGenerator = DEFAULT_PATH_GENERATOR;
7678
private static ThymeleafLanguageDriverConfig languageDriverConfig = DEFAULT_LANGUAGE_DRIVER_CONFIG;
7779

80+
private static ConcurrentMap<ProviderContext, String> cache = new ConcurrentHashMap<>();
81+
7882
/**
7983
* Set custom implementation for {@link PathGenerator}.
8084
*
@@ -124,7 +128,16 @@ public static void setLanguageDriverConfig(ThymeleafLanguageDriverConfig languag
124128
* @return an SQL scripting string(template file path)
125129
*/
126130
public static String provideSql(ProviderContext context) {
127-
return providePath(context.getMapperType(), context.getMapperMethod(), context.getDatabaseId());
131+
return languageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled()
132+
? cache.computeIfAbsent(context, c -> providePath(c.getMapperType(), c.getMapperMethod(), c.getDatabaseId()))
133+
: providePath(context.getMapperType(), context.getMapperMethod(), context.getDatabaseId());
134+
}
135+
136+
/**
137+
* Clear cache.
138+
*/
139+
public static void clearCache() {
140+
cache.clear();
128141
}
129142

130143
static String providePath(Class<?> mapperType, Method mapperMethod, String databaseId) {
@@ -183,7 +196,6 @@ private static String generateTemplatePath(Class<?> type, Method method, String
183196
path.append('-').append(databaseId);
184197
}
185198
path.append(".sql");
186-
System.out.println(path);
187199
return path.toString();
188200
}
189201

src/test/java/org/mybatis/scripting/thymeleaf/ThymeleafLanguageDriverTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ void testCustomWithCustomConfigFileUsingMethodArgument() {
227227
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
228228
Assertions.assertFalse(
229229
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
230+
Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
230231

231232
}
232233

@@ -245,6 +246,7 @@ void testCustomWithCustomizerFunction() {
245246
c.getTemplateFile().getPathProvider().setIncludesPackagePath(false);
246247
c.getTemplateFile().getPathProvider().setSeparateDirectoryPerMapper(false);
247248
c.getTemplateFile().getPathProvider().setIncludesMapperNameWhenSeparateDirectory(false);
249+
c.getTemplateFile().getPathProvider().setCacheEnabled(false);
248250
c.getDialect().setPrefix("mbs");
249251
c.getDialect().setLikeEscapeChar('~');
250252
c.getDialect().setLikeEscapeClauseFormat("escape '%s'");
@@ -289,6 +291,7 @@ void testCustomWithCustomizerFunction() {
289291
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
290292
Assertions.assertFalse(
291293
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
294+
Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
292295
}
293296

294297
@Test
@@ -307,6 +310,7 @@ void testCustomWithBuilderUsingCustomProperties() {
307310
customProperties.setProperty("template-file.path-provider.includes-package-path", "false");
308311
customProperties.setProperty("template-file.path-provider.separate-directory-per-mapper", "false");
309312
customProperties.setProperty("template-file.path-provider.includes-mapper-name-when-separate-directory", "false");
313+
customProperties.setProperty("template-file.path-provider.cache-enabled", "false");
310314
customProperties.setProperty("dialect.prefix", "mbs");
311315
customProperties.setProperty("dialect.like-escape-char", "~");
312316
customProperties.setProperty("dialect.like-escape-clause-format", "escape '%s'");
@@ -353,6 +357,7 @@ void testCustomWithBuilderUsingCustomProperties() {
353357
.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isSeparateDirectoryPerMapper());
354358
Assertions.assertFalse(
355359
thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isIncludesMapperNameWhenSeparateDirectory());
360+
Assertions.assertFalse(thymeleafLanguageDriverConfig.getTemplateFile().getPathProvider().isCacheEnabled());
356361
}
357362

358363
@Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Copyright 2018-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.scripting.thymeleaf.integrationtest;
17+
18+
import java.io.Reader;
19+
import java.sql.Connection;
20+
21+
import org.apache.ibatis.io.Resources;
22+
import org.apache.ibatis.jdbc.ScriptRunner;
23+
import org.apache.ibatis.mapping.Environment;
24+
import org.apache.ibatis.session.Configuration;
25+
import org.apache.ibatis.session.SqlSession;
26+
import org.apache.ibatis.session.SqlSessionFactory;
27+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
28+
import org.apache.ibatis.transaction.TransactionFactory;
29+
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
30+
import org.hsqldb.jdbc.JDBCDataSource;
31+
import org.junit.jupiter.api.Assertions;
32+
import org.junit.jupiter.api.BeforeAll;
33+
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
35+
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriver;
36+
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig;
37+
import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name;
38+
import org.mybatis.scripting.thymeleaf.integrationtest.mapper.TemplateFilePathProviderMapper;
39+
40+
@DisabledIfSystemProperty(named = "mybatis.version", matches = "3\\.4\\..*|3\\.5\\.0")
41+
class TemplateFilePathProviderMapperNoCacheTest {
42+
private static SqlSessionFactory sqlSessionFactory;
43+
44+
@BeforeAll
45+
static void setUp() throws Exception {
46+
Class.forName("org.hsqldb.jdbcDriver");
47+
JDBCDataSource dataSource = new JDBCDataSource();
48+
dataSource.setUrl("jdbc:hsqldb:mem:db1");
49+
dataSource.setUser("sa");
50+
dataSource.setPassword("");
51+
52+
try (Connection conn = dataSource.getConnection()) {
53+
try (Reader reader = Resources.getResourceAsReader("create-db.sql")) {
54+
ScriptRunner runner = new ScriptRunner(conn);
55+
runner.setLogWriter(null);
56+
runner.setErrorLogWriter(null);
57+
runner.runScript(reader);
58+
conn.commit();
59+
}
60+
}
61+
62+
TransactionFactory transactionFactory = new JdbcTransactionFactory();
63+
Environment environment = new Environment("development", transactionFactory, dataSource);
64+
65+
Configuration configuration = new Configuration(environment);
66+
configuration.setMapUnderscoreToCamelCase(true);
67+
configuration.getLanguageRegistry()
68+
.register(new ThymeleafLanguageDriver(ThymeleafLanguageDriverConfig.newInstance(c -> {
69+
c.getTemplateFile().getPathProvider().setPrefix("sql/");
70+
c.getTemplateFile().getPathProvider().setIncludesPackagePath(false);
71+
c.getTemplateFile().getPathProvider().setCacheEnabled(false);
72+
})));
73+
configuration.setDefaultScriptingLanguage(ThymeleafLanguageDriver.class);
74+
75+
configuration.addMapper(TemplateFilePathProviderMapper.class);
76+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
77+
}
78+
79+
@Test
80+
void testInsert() {
81+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
82+
TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
83+
Name name = new Name();
84+
name.setFirstName("Thymeleaf");
85+
name.setLastName("MyBatis");
86+
mapper.insert(name);
87+
88+
Name loadedName = mapper.findById(name.getId());
89+
Assertions.assertEquals(name.getFirstName(), loadedName.getFirstName());
90+
Assertions.assertEquals(name.getLastName(), loadedName.getLastName());
91+
}
92+
}
93+
94+
@Test
95+
void testUpdate() {
96+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
97+
TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
98+
Name name = new Name();
99+
name.setFirstName("Thymeleaf");
100+
name.setLastName("MyBatis");
101+
mapper.insert(name);
102+
103+
Name updatingName = new Name();
104+
updatingName.setId(name.getId());
105+
updatingName.setFirstName("Thymeleaf3");
106+
mapper.update(updatingName);
107+
108+
Name loadedName = mapper.findById(name.getId());
109+
Assertions.assertEquals(updatingName.getFirstName(), loadedName.getFirstName());
110+
Assertions.assertEquals(name.getLastName(), loadedName.getLastName());
111+
}
112+
}
113+
114+
@Test
115+
void testDelete() {
116+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
117+
TemplateFilePathProviderMapper mapper = sqlSession.getMapper(TemplateFilePathProviderMapper.class);
118+
Name name = new Name();
119+
name.setFirstName("Thymeleaf");
120+
name.setLastName("MyBatis");
121+
mapper.insert(name);
122+
123+
mapper.delete(name);
124+
125+
Name loadedName = mapper.findById(name.getId());
126+
Assertions.assertNull(loadedName);
127+
}
128+
}
129+
130+
}

src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.ibatis.transaction.TransactionFactory;
2929
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
3030
import org.hsqldb.jdbc.JDBCDataSource;
31+
import org.junit.jupiter.api.AfterAll;
3132
import org.junit.jupiter.api.Assertions;
3233
import org.junit.jupiter.api.BeforeAll;
3334
import org.junit.jupiter.api.Test;
@@ -36,11 +37,18 @@
3637
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig;
3738
import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name;
3839
import org.mybatis.scripting.thymeleaf.integrationtest.mapper.TemplateFilePathProviderMapper;
40+
import org.mybatis.scripting.thymeleaf.support.TemplateFilePathProvider;
3941

4042
@DisabledIfSystemProperty(named = "mybatis.version", matches = "3\\.4\\..*|3\\.5\\.0")
4143
class TemplateFilePathProviderMapperTest {
4244
private static SqlSessionFactory sqlSessionFactory;
4345

46+
@BeforeAll
47+
@AfterAll
48+
static void cleanup() {
49+
TemplateFilePathProvider.clearCache();
50+
}
51+
4452
@BeforeAll
4553
static void setUp() throws Exception {
4654
Class.forName("org.hsqldb.jdbcDriver");

src/test/resources/mybatis-thymeleaf-custom.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ template-file.path-provider.prefix=sqls/
2525
template-file.path-provider.includes-package-path=false
2626
template-file.path-provider.separate-directory-per-mapper=false
2727
template-file.path-provider.includes-mapper-name-when-separate-directory=false
28+
template-file.path-provider.cache-enabled=false
2829
dialect.prefix=mybatis
2930
dialect.like-escape-char=~
3031
dialect.like-escape-clause-format=escape '%s'

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy