From 3abeb075547aa5bacf0b40ee87d97502b1fb7d06 Mon Sep 17 00:00:00 2001 From: Kazuki Shimizu Date: Sun, 14 Apr 2019 14:39:41 +0900 Subject: [PATCH] Add SQL provider class that help detecting a template file automatically Fixes gh-10 --- .travis.yml | 6 +- pom.xml | 12 + src/main/asciidoc/user-guide.adoc | 70 +++++ .../support/TemplateFilePathProvider.java | 289 ++++++++++++++++++ .../thymeleaf/support/package-info.java | 21 ++ .../TemplateFilePathProviderMapperTest.java | 127 ++++++++ .../TemplateFilePathProviderMapper.java | 41 +++ .../thymeleaf/support/BaseMapper.java | 26 ++ .../support/TemplateFilePathProviderTest.java | 149 +++++++++ .../thymeleaf/support/TestMapper.java | 29 ++ .../support/BaseMapper/BaseMapper-count.sql | 16 + .../BaseMapper/BaseMapper-insert-h2.sql | 16 + .../support/BaseMapper/BaseMapper-insert.sql | 16 + .../support/BaseMapper_selectOne.sql | 16 + .../support/TestMapper/TestMapper-delete.sql | 16 + .../TestMapper/TestMapper-update-h2.sql | 16 + .../support/TestMapper/TestMapper-update.sql | 16 + .../support/TestMapper/selectAllAsc.sql | 16 + .../support/sql/TestMapper-selectAllDesc.sql | 16 + .../TemplateFilePathProviderMapper-delete.sql | 18 ++ ...emplateFilePathProviderMapper-findById.sql | 18 ++ .../TemplateFilePathProviderMapper-insert.sql | 18 ++ .../TemplateFilePathProviderMapper-update.sql | 25 ++ 23 files changed, 990 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProvider.java create mode 100644 src/main/java/org/mybatis/scripting/thymeleaf/support/package-info.java create mode 100644 src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/TemplateFilePathProviderMapperTest.java create mode 100644 src/test/java/org/mybatis/scripting/thymeleaf/integrationtest/mapper/TemplateFilePathProviderMapper.java create mode 100644 src/test/java/org/mybatis/scripting/thymeleaf/support/BaseMapper.java create mode 100644 src/test/java/org/mybatis/scripting/thymeleaf/support/TemplateFilePathProviderTest.java create mode 100644 src/test/java/org/mybatis/scripting/thymeleaf/support/TestMapper.java create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-count.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert-h2.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper/BaseMapper-insert.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/BaseMapper_selectOne.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-delete.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update-h2.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/TestMapper-update.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/TestMapper/selectAllAsc.sql create mode 100644 src/test/resources/org/mybatis/scripting/thymeleaf/support/sql/TestMapper-selectAllDesc.sql create mode 100644 src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-delete.sql create mode 100644 src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-findById.sql create mode 100644 src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-insert.sql create mode 100644 src/test/resources/sql/TemplateFilePathProviderMapper/TemplateFilePathProviderMapper-update.sql 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 /*[/]*/