diff --git a/.travis.yml b/.travis.yml index 18b5d53..61998f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,10 @@ jdk: - oraclejdk8 script: - # build using mybatis latest version + # build using mybatis latest released version - ./mvnw clean verify - # build using mybatis 3.4.x line - - ./mvnw clean verify -Dmybatis.version=3.4.6 + # test using mybatis 3.4.x line + - ./mvnw test -Dmybatis.version=3.4.6 # build using mybatis 3.5.x snapshot - ./mvnw clean verify -Dmybatis.version=3.5.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index 33ab245..1ba5bfe 100644 --- a/pom.xml +++ b/pom.xml @@ -117,6 +117,18 @@ + + + + maven-surefire-plugin + + + ${mybatis.version} + + + + + org.asciidoctor diff --git a/src/main/asciidoc/user-guide.adoc b/src/main/asciidoc/user-guide.adoc index 1ae0c93..75f542f 100644 --- a/src/main/asciidoc/user-guide.adoc +++ b/src/main/asciidoc/user-guide.adoc @@ -963,6 +963,76 @@ using <>. AND firstName LIKE #{patternFirstName} ESCAPE '\' ---- +== Support classes + +We provides useful classes for supporting development. + +=== TemplateFilePathProvider + +The `TemplateFilePathProvider` is SQL provider class that return the SQL template file path(Available since 1.0.1). +This class use with SQL provider annotation(`@InsertProvider`, `@UpdateProvider`, `@DeleteProvider` and `@SelectProvider`}) as follow: + +[NOTE] +==== +**This class required to use on MyBatis 3.5.1+.** +==== + +.Usage: + +[source, java] +---- +package com.example.mapper; + +public interface BaseMapper { + + @Options(useGeneratedKeys = true, keyProperty = "id") + @InsertProvider(type = TemplateFilePathProvider.class) + void insert(T entity); + + @UpdateProvider(type = TemplateFilePathProvider.class) + void update(T entity); + + @DeleteProvider(type = TemplateFilePathProvider.class) + void delete(T entity); + + @SelectProvider(type = TemplateFilePathProvider.class) + T findById(Integer id); + +} +---- + +[source, java] +---- +package com.example.mapper; + +public interface NameMapper extends BaseMapper { + + @SelectProvider(type = TemplateFilePathProvider.class) + List findByCondition(NameCondition condition); + +} +---- + +By default implementation, a template file path resolve following format and priority order. +If does not match all, it throw an exception that indicate not found a template file. + +* `com/example/mapper/NameMapper/NameMapper-{methodName}-{databaseId}.sql` +* `com/example/mapper/NameMapper/NameMapper-{methodName}.sql` + + (fallback using default database) +* `com/example/mapper/BaseMapper/BaseMapper-{methodName}-{databaseId}.sql` + + (fallback using declaring class of mapper method) +* `com/example/mapper/BaseMapper/BaseMapper-{methodName}.sql` + + (fallback using declaring class of mapper method and default database) + +If you want to customize the template file path format, +please call static setter methods of the `TemplateFilePathProvider` **before initialize the MyBatis module**. + +[NOTE] +==== +If you applied an user defined `ThymeleafLanguageDriverConfig` for `ThymeleafLanguageDriver`, +please apply same instance to the `TemplateFilePathProvider` using the `setLanguageDriverConfig` method. +==== + == Cautions for usage diff --git a/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java b/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java new file mode 100644 index 0000000..7654641 --- /dev/null +++ b/src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java @@ -0,0 +1,289 @@ +/** + * 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.support; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Optional; + +import org.apache.ibatis.builder.annotation.ProviderContext; +import org.apache.ibatis.io.Resources; +import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriver; +import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig; + +/** + * The SQL provider class that return the SQL template file path.
+ * IMPORTANT: This class required to use with mybatis 3.5.1+ and need to use with SQL provider annotation (such + * as {@link org.apache.ibatis.annotations.SelectProvider} as follow:
+ *
+ * + *
+ * package com.example.mapper;
+ *
+ * public interface BaseMapper<T> {
+ *
+ *   @Options(useGeneratedKeys = true, keyProperty = "id")
+ *   @InsertProvider(type = TemplateFilePathProvider.class)
+ *   void insert(T entity);
+ *
+ *   @UpdateProvider(type = TemplateFilePathProvider.class)
+ *   void update(T entity);
+ *
+ *   @DeleteProvider(type = TemplateFilePathProvider.class)
+ *   void delete(T entity);
+ *
+ *   @SelectProvider(type = TemplateFilePathProvider.class)
+ *   T findById(Integer id);
+ *
+ * }
+ * 
+ * + *
+ * package com.example.mapper;
+ *
+ * public interface NameMapper extends BaseMapper {
+ *
+ *   @SelectProvider(type = TemplateFilePathProvider.class)
+ *   List<Name> findByConditions(NameConditions conditions);
+ *
+ * }
+ * 
+ * + * @author Kazuki Shimizu + * @version 1.0.1 + */ +public class TemplateFilePathProvider { + + private static final PathGenerator DEFAULT_PATH_GENERATOR = TemplateFilePathProvider::generateTemplatePath; + private static final ThymeleafLanguageDriverConfig DEFAULT_LANGUAGE_DRIVER_CONFIG = ThymeleafLanguageDriverConfig + .newInstance(); + + private static String prefix = ""; + private static boolean includesPackagePath = true; + private static boolean separateDirectoryPerMapper = true; + private static boolean includesMapperNameWhenSeparateDirectory = true; + private static PathGenerator pathGenerator = DEFAULT_PATH_GENERATOR; + private static ThymeleafLanguageDriverConfig languageDriverConfig = DEFAULT_LANGUAGE_DRIVER_CONFIG; + + /** + * Set a prefix for adding to template file path. + *

+ * Default is {@code ""}. + *

+ * + * @param prefix + * a prefix for adding to template file path + */ + public static void setPrefix(String prefix) { + TemplateFilePathProvider.prefix = Optional.ofNullable(prefix).orElse(""); + } + + /** + * Set whether includes package path part. + *

+ * Default is {@code true}. + *

+ * + * @param includesPackagePath + * If want to includes, set {@code true} + */ + public static void setIncludesPackagePath(boolean includesPackagePath) { + TemplateFilePathProvider.includesPackagePath = includesPackagePath; + } + + /** + * Set whether separate directory per mapper. + *

+ * Default is {@code true}. + *

+ * + * @param separateDirectoryPerMapper + * If want to separate directory, set {@code true} + */ + public static void setSeparateDirectoryPerMapper(boolean separateDirectoryPerMapper) { + TemplateFilePathProvider.separateDirectoryPerMapper = separateDirectoryPerMapper; + } + + /** + * Set whether includes mapper name into file name when separate directory per mapper. + *

+ * Default is {@code true}. + *

+ * + * @param includesMapperNameWhenSeparateDirectory + * If want to includes, set {@code true} + */ + public static void setIncludesMapperNameWhenSeparateDirectory(boolean includesMapperNameWhenSeparateDirectory) { + TemplateFilePathProvider.includesMapperNameWhenSeparateDirectory = includesMapperNameWhenSeparateDirectory; + } + + /** + * Set custom implementation for {@link PathGenerator}. + * + * @param generator + * a instance for generating a template file path + */ + public static void setCustomTemplateFilePathGenerator(PathGenerator generator) { + TemplateFilePathProvider.pathGenerator = Optional.ofNullable(generator).orElse(DEFAULT_PATH_GENERATOR); + } + + /** + * Set a configuration instance for {@link ThymeleafLanguageDriver}. + *

+ * By default, {@link ThymeleafLanguageDriverConfig#newInstance()} will used. + *

+ *

+ * If you applied an user define {@link ThymeleafLanguageDriverConfig} for {@link ThymeleafLanguageDriver}, please + * same instance to the this class. + *

+ * + * @param languageDriverConfig + * A user defined {@link ThymeleafLanguageDriverConfig} + */ + public static void setLanguageDriverConfig(ThymeleafLanguageDriverConfig languageDriverConfig) { + TemplateFilePathProvider.languageDriverConfig = Optional.ofNullable(languageDriverConfig) + .orElse(DEFAULT_LANGUAGE_DRIVER_CONFIG); + } + + /** + * Provide an SQL scripting string(template file path). + * + *
+ * By default implementation, a template file path resolve following format and priority order. If does not match all, + * it throw an exception that indicate not found a template file. + *
    + *
  • com/example/mapper/NameMapper/NameMapper-{methodName}-{databaseId}.sql
  • + *
  • com/example/mapper/NameMapper/NameMapper-{methodName}.sql (fallback using default database)
  • + *
  • com/example/mapper/BaseMapper/BaseMapper-{methodName}-{databaseId}.sql (fallback using declaring class of + * method)
  • + *
  • com/example/mapper/BaseMapper/BaseMapper-{methodName}.sql (fallback using declaring class of method and default + * database)
  • + *
+ *
+ * If you want to customize path format, please call the following methods on application initialize phase. + *
    + *
  • {@link #setPrefix(String)}
  • + *
  • {@link #setIncludesPackagePath(boolean)}
  • + *
  • {@link #setSeparateDirectoryPerMapper(boolean)}
  • + *
  • {@link #setIncludesMapperNameWhenSeparateDirectory(boolean)}
  • + *
  • {@link #setLanguageDriverConfig(ThymeleafLanguageDriverConfig)}
  • + *
  • {@link #setCustomTemplateFilePathGenerator(PathGenerator)}
  • + *
+ * + * @param context + * a context of SQL provider + * @return an SQL scripting string(template file path) + */ + public static String provideSql(ProviderContext context) { + return providePath(context.getMapperType(), context.getMapperMethod(), context.getDatabaseId()); + } + + static String providePath(Class mapperType, Method mapperMethod, String databaseId) { + boolean fallbackDeclaringClass = mapperType != mapperMethod.getDeclaringClass(); + boolean fallbackDatabase = databaseId != null; + String path = pathGenerator.generatePath(mapperType, mapperMethod, databaseId); + if (exists(path)) { + return path; + } + if (fallbackDatabase) { + path = pathGenerator.generatePath(mapperType, mapperMethod, null); + if (exists(path)) { + return path; + } + } + if (fallbackDeclaringClass) { + path = pathGenerator.generatePath(mapperMethod.getDeclaringClass(), mapperMethod, databaseId); + if (exists(path)) { + return path; + } + } + if (fallbackDatabase) { + path = pathGenerator.generatePath(mapperMethod.getDeclaringClass(), mapperMethod, null); + if (exists(path)) { + return path; + } + } + throw new IllegalStateException("The SQL template file not found. mapperType:[" + mapperType + "] mapperMethod:[" + + mapperMethod + "] databaseId:[" + databaseId + "]"); + } + + private static String generateTemplatePath(Class type, Method method, String databaseId) { + Package pkg = type.getPackage(); + String packageName = pkg == null ? "" : pkg.getName(); + String className = type.getName().substring(packageName.length() + (packageName.length() == 0 ? 0 : 1)); + + StringBuilder path = new StringBuilder(); + if (!prefix.isEmpty()) { + path.append(prefix); + } + if (includesPackagePath && !packageName.isEmpty()) { + path.append(packageName.replace('.', '/')).append('/'); + } + path.append(className); + if (separateDirectoryPerMapper) { + path.append('/'); + if (includesMapperNameWhenSeparateDirectory) { + path.append(className).append('-'); + } + } else { + path.append('-'); + } + path.append(method.getName()); + if (databaseId != null) { + path.append('-').append(databaseId); + } + path.append(".sql"); + return path.toString(); + } + + private static boolean exists(String path) { + String actualPath; + if (languageDriverConfig.getTemplateFile().getBaseDir().isEmpty()) { + actualPath = path; + } else { + actualPath = languageDriverConfig.getTemplateFile().getBaseDir().endsWith("/") + ? languageDriverConfig.getTemplateFile().getBaseDir() + path + : languageDriverConfig.getTemplateFile().getBaseDir() + "/" + path; + } + try { + return Resources.getResourceAsFile(actualPath).exists(); + } catch (IOException e) { + return false; + } + } + + /** + * The interface that implements a function for generating template file path. + */ + @FunctionalInterface + public interface PathGenerator { + + /** + * Generate a template file path. + * + * @param type + * mapper interface type that specified provider (or declaring interface type of mapper method) + * @param method + * a mapper method that specified provider + * @param databaseId + * a database id that provided from {@link org.apache.ibatis.mapping.DatabaseIdProvider} + * @return a template file path + */ + String generatePath(Class type, Method method, String databaseId); + + } + +} diff --git a/src/main/java/org/mybatis/scripting/thymeleaf/support/package-info.java b/src/main/java/org/mybatis/scripting/thymeleaf/support/package-info.java new file mode 100644 index 0000000..30aded5 --- /dev/null +++ b/src/main/java/org/mybatis/scripting/thymeleaf/support/package-info.java @@ -0,0 +1,21 @@ +/** + * 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. + */ +/** + * The package that holds classes for supports development. + * + * @since 1.0.1 + */ +package org.mybatis.scripting.thymeleaf.support; \ No newline at end of file diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java new file mode 100644 index 0000000..a370a92 --- /dev/null +++ b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java @@ -0,0 +1,127 @@ +/** + * 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.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 + 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(); + } + } + + TemplateFilePathProvider.setPrefix("sql/"); + TemplateFilePathProvider.setIncludesPackagePath(false); + + TransactionFactory transactionFactory = new JdbcTransactionFactory(); + Environment environment = new Environment("development", transactionFactory, dataSource); + + Configuration configuration = new Configuration(environment); + configuration.setMapUnderscoreToCamelCase(true); + 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/mapper/TemplateFilePathProviderMapper.java b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/mapper/TemplateFilePathProviderMapper.java new file mode 100644 index 0000000..9b2bc37 --- /dev/null +++ b/src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/mapper/TemplateFilePathProviderMapper.java @@ -0,0 +1,41 @@ +/** + * 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.mapper; + +import org.apache.ibatis.annotations.DeleteProvider; +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Options; +import org.apache.ibatis.annotations.SelectProvider; +import org.apache.ibatis.annotations.UpdateProvider; +import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name; +import org.mybatis.scripting.thymeleaf.support.TemplateFilePathProvider; + +public interface TemplateFilePathProviderMapper { + + @Options(useGeneratedKeys = true, keyProperty = "id") + @InsertProvider(type = TemplateFilePathProvider.class) + void insert(Name name); + + @UpdateProvider(type = TemplateFilePathProvider.class) + void update(Name name); + + @DeleteProvider(type = TemplateFilePathProvider.class) + void delete(Name name); + + @SelectProvider(type = TemplateFilePathProvider.class) + Name findById(Integer id); + +} diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/support/BaseMapper.java b/src/test/java/org/mybatis/scripting/thymeleaf/support/BaseMapper.java new file mode 100644 index 0000000..6bd3e82 --- /dev/null +++ b/src/test/java/org/mybatis/scripting/thymeleaf/support/BaseMapper.java @@ -0,0 +1,26 @@ +/** + * 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.support; + +public interface BaseMapper { + void insert(T model); + + void update(T model); + + long count(); + + T selectOne(int id); +} diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProviderTest.java b/src/test/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProviderTest.java new file mode 100644 index 0000000..d82c717 --- /dev/null +++ b/src/test/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProviderTest.java @@ -0,0 +1,149 @@ +/** + * 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.support; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; +import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig; + +@DisabledIfSystemProperty(named = "mybatis.version", matches = "3\\.4\\..*|3\\.5\\.0") +class TemplateFilePathProviderTest { + + @BeforeEach + @AfterEach + void clean() { + TemplateFilePathProvider.setPrefix(null); + TemplateFilePathProvider.setIncludesPackagePath(true); + TemplateFilePathProvider.setSeparateDirectoryPerMapper(true); + TemplateFilePathProvider.setIncludesMapperNameWhenSeparateDirectory(true); + TemplateFilePathProvider.setCustomTemplateFilePathGenerator(null); + TemplateFilePathProvider.setLanguageDriverConfig(null); + } + + @Test + void withoutDatabaseId() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "update"), + null); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update.sql", path); + } + + @Test + void withDatabaseId() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "update"), + "h2"); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update-h2.sql", path); + } + + @Test + void fallbackWithDefaultDatabase() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "delete"), + "h2"); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-delete.sql", path); + } + + @Test + void fallbackDeclaringClassWithoutDatabaseId() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "insert"), + null); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert.sql", path); + } + + @Test + void fallbackDeclaringClassWithDatabaseId() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "insert"), + "h2"); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert-h2.sql", path); + } + + @Test + void fallbackDeclaringClassAndDefaultDatabase() { + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "count"), + "h2"); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-count.sql", path); + } + + @Test + void notFoundSqlFile() { + IllegalStateException e = Assertions.assertThrows(IllegalStateException.class, () -> { + TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "selectOne"), "h2"); + }); + Assertions.assertEquals( + "The SQL template file not found. mapperType:[interface org.mybatis.scripting.thymeleaf.support.TestMapper] mapperMethod:[public abstract java.lang.Object org.mybatis.scripting.thymeleaf.support.BaseMapper.selectOne(int)] databaseId:[h2]", + e.getMessage()); + } + + @Test + void includesPackagePathAndSeparatesDirectoryPerMapperIsFalse() { + TemplateFilePathProvider.setIncludesPackagePath(false); + TemplateFilePathProvider.setSeparateDirectoryPerMapper(false); + TemplateFilePathProvider.setLanguageDriverConfig(ThymeleafLanguageDriverConfig + .newInstance(c -> c.getTemplateFile().setBaseDir("org/mybatis/scripting/thymeleaf/support/sql"))); + String path = TemplateFilePathProvider.providePath(TestMapper.class, + extractMethod(TestMapper.class, "selectAllDesc"), null); + Assertions.assertEquals("TestMapper-selectAllDesc.sql", path); + } + + @Test + void baseDirEndWithSlash() { + TemplateFilePathProvider.setIncludesPackagePath(false); + TemplateFilePathProvider.setSeparateDirectoryPerMapper(false); + TemplateFilePathProvider.setLanguageDriverConfig(ThymeleafLanguageDriverConfig + .newInstance(c -> c.getTemplateFile().setBaseDir("org/mybatis/scripting/thymeleaf/support/sql/"))); + String path = TemplateFilePathProvider.providePath(TestMapper.class, + extractMethod(TestMapper.class, "selectAllDesc"), null); + Assertions.assertEquals("TestMapper-selectAllDesc.sql", path); + } + + @Test + void includesMapperNameWhenSeparateDirectoryIsFalse() { + TemplateFilePathProvider.setIncludesMapperNameWhenSeparateDirectory(false); + String path = TemplateFilePathProvider.providePath(TestMapper.class, + extractMethod(TestMapper.class, "selectAllAsc"), null); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/TestMapper/selectAllAsc.sql", path); + } + + @Test + void prefix() { + TemplateFilePathProvider.setPrefix("org/mybatis/scripting/thymeleaf/support/sql/"); + TemplateFilePathProvider.setIncludesPackagePath(false); + TemplateFilePathProvider.setSeparateDirectoryPerMapper(false); + String path = TemplateFilePathProvider.providePath(TestMapper.class, + extractMethod(TestMapper.class, "selectAllDesc"), null); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/sql/TestMapper-selectAllDesc.sql", path); + } + + @Test + void customTemplateFileGenerator() { + TemplateFilePathProvider.setCustomTemplateFilePathGenerator( + (type, method, databaseId) -> type.getName().replace('.', '/') + "_" + method.getName() + ".sql"); + String path = TemplateFilePathProvider.providePath(TestMapper.class, extractMethod(TestMapper.class, "selectOne"), + null); + Assertions.assertEquals("org/mybatis/scripting/thymeleaf/support/BaseMapper_selectOne.sql", path); + + } + + private Method extractMethod(Class type, String methodName) { + return Arrays.stream(type.getMethods()).filter(m -> m.getName().equals(methodName)).findFirst().orElseThrow( + () -> new IllegalArgumentException("The method not found. type:" + type + " methodName:" + methodName)); + } + +} diff --git a/src/test/java/org/mybatis/scripting/thymeleaf/support/TestMapper.java b/src/test/java/org/mybatis/scripting/thymeleaf/support/TestMapper.java new file mode 100644 index 0000000..c647684 --- /dev/null +++ b/src/test/java/org/mybatis/scripting/thymeleaf/support/TestMapper.java @@ -0,0 +1,29 @@ +/** + * 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.support; + +import java.util.List; + +import org.mybatis.scripting.thymeleaf.integrationtest.domain.Name; + +interface TestMapper extends BaseMapper { + void delete(int id); + + List selectAllDesc(); + + List selectAllAsc(); + +} diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-count.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-count.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-count.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert-h2.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert-h2.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert-h2.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper_selectOne.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper_selectOne.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper_selectOne.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-delete.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-delete.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-delete.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update-h2.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update-h2.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update-h2.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/selectAllAsc.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/selectAllAsc.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/selectAllAsc.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/org/mybatis/scripting/thymeleaf/support/sql/TestMapper-selectAllDesc.sql b/src/test/resources/org/mybatis/scripting/thymeleaf/support/sql/TestMapper-selectAllDesc.sql new file mode 100644 index 0000000..06a28d5 --- /dev/null +++ b/src/test/resources/org/mybatis/scripting/thymeleaf/support/sql/TestMapper-selectAllDesc.sql @@ -0,0 +1,16 @@ +-- +-- 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. +-- + diff --git a/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-delete.sql b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-delete.sql new file mode 100644 index 0000000..652e80a --- /dev/null +++ b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-delete.sql @@ -0,0 +1,18 @@ +-- +-- 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. +-- + +DELETE FROM names + WHERE id = /*[# mb:p="id,typeHandler=org.apache.ibatis.type.IntegerTypeHandler"]*/ 1 /*[/]*/ diff --git a/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-findById.sql b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-findById.sql new file mode 100644 index 0000000..dc4d1d9 --- /dev/null +++ b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-findById.sql @@ -0,0 +1,18 @@ +-- +-- 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. +-- + +SELECT * FROM names + /*[# th:insert="~{sql/NameMapper/findByIdWhere.sql}" /]*/ diff --git a/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-insert.sql b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-insert.sql new file mode 100644 index 0000000..d4189f3 --- /dev/null +++ b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-insert.sql @@ -0,0 +1,18 @@ +-- +-- 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. +-- + +INSERT INTO names (firstName, lastName) + VALUES (/*[# mb:p="firstName"]*/ 'Taro' /*[/]*/, /*[# mb:p="lastName"]*/ 'Yamada' /*[/]*/) diff --git a/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-update.sql b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-update.sql new file mode 100644 index 0000000..b05d3a0 --- /dev/null +++ b/src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-update.sql @@ -0,0 +1,25 @@ +-- +-- 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. +-- + +UPDATE names + SET id = id + /*[# th:if="${firstName} != null"]*/ + ,firstName = /*[# mb:p="firstName"]*/ 'Taro' /*[/]*/ + /*[/]*/ + /*[# th:if="${lastName} != null"]*/ + ,lastName = /*[# mb:p="lastName"]*/ 'Yamada' /*[/]*/ + /*[/]*/ + WHERE id = /*[# mb:p="id"]*/ 1 /*[/]*/ 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