diff --git a/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm b/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm
index 9b854bdc1..8e804d504 100644
--- a/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm
+++ b/mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm
@@ -525,6 +525,36 @@ ThymeleafLanguageDriverConfig thymeleafLanguageDriverConfig() {
Shows how to use a Mapper that has its statements in an xml file and Dao that uses an SqlSesionTemplate.
+
+ Shows how to use the language driver for Velocity with mybatis-velocity.
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml
new file mode 100644
index 000000000..dc8a38327
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/format.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt
new file mode 100644
index 000000000..4ce1777ad
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/license.txt
@@ -0,0 +1,13 @@
+ Copyright ${license.git.copyrightYears} 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/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml
new file mode 100644
index 000000000..620526cfb
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/pom.xml
@@ -0,0 +1,81 @@
+
+
+
+ 4.0.0
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-samples
+ 2.1.0-SNAPSHOT
+
+ mybatis-spring-boot-sample-freemarker-legacy
+ jar
+ mybatis-spring-boot-sample-freemarker-legacy
+
+ org.mybatis.spring.boot.sample.legacyfreemarker
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.mybatis.scripting
+ mybatis-freemarker
+ 1.1.2
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java
new file mode 100644
index 000000000..fa4d2addf
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import sample.mybatis.mapper.CityMapper;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class SampleFreeMarkerApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleFreeMarkerApplication.class, args);
+ }
+
+ private final CityMapper cityMapper;
+
+ public SampleFreeMarkerApplication(CityMapper cityMapper) {
+ this.cityMapper = cityMapper;
+ }
+
+ @Override
+ @SuppressWarnings("squid:S106")
+ public void run(String... args) {
+ System.out.println(this.cityMapper.findByState("CA"));
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java
new file mode 100644
index 000000000..afac2ab2a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/domain/City.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2015-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 sample.mybatis.domain;
+
+import java.io.Serializable;
+
+/**
+ * @author Kazuki Shimizu
+ */
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private String country;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ @Override
+ public String toString() {
+ return getId() + "," + getName() + "," + getState() + "," + getCountry();
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java
new file mode 100644
index 000000000..b5221e71d
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import sample.mybatis.domain.City;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@Mapper
+public interface CityMapper {
+
+ @Select("select id, name, state, country from city where id = <@p name='id'/>")
+ City findById(@Param("id") Long id);
+
+ @Select("/mappers/CityMapper-findByState.ftl")
+ City findByState(@Param("state") String state);
+
+ City findByName(@Param("name") String name);
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties
new file mode 100644
index 000000000..fd28c0490
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Copyright 2015-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.
+#
+
+logging.level.root=WARN
+logging.level.sample.mybatis.mapper=TRACE
+
+mybatis.mapper-locations=classpath*:/mappers/*.xml
+mybatis.type-aliases-package=sample.mybatis.domain
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql
new file mode 100644
index 000000000..4e42e5bc2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/data.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright 2015-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 city (name, state, country) values ('San Francisco', 'CA', 'US');
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl
new file mode 100644
index 000000000..e79b67d8c
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper-findByState.ftl
@@ -0,0 +1,23 @@
+<#--
+
+ Copyright 2015-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
+ id, name, state, country
+from
+ city
+where
+ state = <@p name="state"/>
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml
new file mode 100644
index 000000000..33503e0da
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/mappers/CityMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql
new file mode 100644
index 000000000..b6751f983
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/main/resources/schema.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2015-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.
+--
+
+drop table if exists city;
+
+create table city (id int primary key auto_increment, name varchar, state varchar, country varchar);
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java
new file mode 100644
index 000000000..a081a89fa
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/extensions/CaptureSystemOutput.java
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2015-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 extensions;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.platform.commons.support.ReflectionSupport;
+
+/**
+ * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and
+ * {@code System.err} with expectations supported via Hamcrest matchers.
+ *
+ *
+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit
+ * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method.
+ *
+ *
+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers.
+ *
+ *
+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Sam Brannen
+ */
+ static class OutputCapture {
+
+ private final List> matchers = new ArrayList<>();
+
+ private CaptureOutputStream captureOut;
+
+ private CaptureOutputStream captureErr;
+
+ private ByteArrayOutputStream copy;
+
+ void captureOutput() {
+ this.copy = new ByteArrayOutputStream();
+ this.captureOut = new CaptureOutputStream(System.out, this.copy);
+ this.captureErr = new CaptureOutputStream(System.err, this.copy);
+ System.setOut(new PrintStream(this.captureOut));
+ System.setErr(new PrintStream(this.captureErr));
+ }
+
+ void releaseOutput() {
+ System.setOut(this.captureOut.getOriginal());
+ System.setErr(this.captureErr.getOriginal());
+ this.copy = null;
+ }
+
+ private void flush() {
+ try {
+ this.captureOut.flush();
+ this.captureErr.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ /**
+ * Verify that the captured output is matched by the supplied {@code matcher}.
+ *
+ *
+ * Verification is performed after the test method has executed.
+ *
+ * @param matcher
+ * the matcher
+ */
+ public void expect(Matcher super String> matcher) {
+ this.matchers.add(matcher);
+ }
+
+ /**
+ * Return all captured output to {@code System.out} and {@code System.err} as a single string.
+ */
+ @Override
+ public String toString() {
+ flush();
+ return this.copy.toString();
+ }
+
+ void reset() {
+ this.matchers.clear();
+ this.copy.reset();
+ }
+
+ private static class CaptureOutputStream extends OutputStream {
+
+ private final PrintStream original;
+
+ private final OutputStream copy;
+
+ CaptureOutputStream(PrintStream original, OutputStream copy) {
+ this.original = original;
+ this.copy = copy;
+ }
+
+ PrintStream getOriginal() {
+ return this.original;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ this.copy.write(b);
+ this.original.write(b);
+ this.original.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.copy.write(b, off, len);
+ this.original.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ this.copy.flush();
+ this.original.flush();
+ }
+
+ }
+
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
new file mode 100644
index 000000000..f0c2275e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import extensions.CaptureSystemOutput;
+import extensions.CaptureSystemOutput.OutputCapture;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@CaptureSystemOutput
+@SpringBootTest
+class SampleMybatisApplicationTest {
+
+ @Test
+ void test(OutputCapture outputCapture) {
+ String output = outputCapture.toString();
+ assertThat(output).contains("1,San Francisco,CA,US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java
new file mode 100644
index 000000000..cf4bf63fc
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.junit.jupiter.api.Test;
+import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
+import sample.mybatis.domain.City;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CityMapper}.
+ *
+ * @author Kazuki Shimizu
+ */
+@MybatisTest
+class CityMapperTest {
+
+ @Autowired
+ private CityMapper cityMapper;
+
+ @Test
+ void findByState() {
+ City city = cityMapper.findByState("CA");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findById() {
+ City city = cityMapper.findById(1L);
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findByName() {
+ City city = cityMapper.findByName("San Francisco");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
new file mode 100644
index 000000000..3f124cebc
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}.
+ *
+ * This class has role for prevent to run the {@link sample.mybatis.SampleFreeMarkerApplication}. For more detail
+ * information, please refer
+ * Here.
+ *
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class MapperTestApplication {
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml
new file mode 100644
index 000000000..dc8a38327
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/format.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt
new file mode 100644
index 000000000..4ce1777ad
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/license.txt
@@ -0,0 +1,13 @@
+ Copyright ${license.git.copyrightYears} 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/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml
new file mode 100644
index 000000000..b99c71a63
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/pom.xml
@@ -0,0 +1,80 @@
+
+
+
+ 4.0.0
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-samples
+ 2.1.0-SNAPSHOT
+
+ mybatis-spring-boot-sample-freemarker
+ jar
+ mybatis-spring-boot-sample-freemarker
+
+ org.mybatis.spring.boot.sample.freemarker
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.mybatis.scripting
+ mybatis-freemarker
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java
new file mode 100644
index 000000000..fa4d2addf
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/SampleFreeMarkerApplication.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import sample.mybatis.mapper.CityMapper;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class SampleFreeMarkerApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleFreeMarkerApplication.class, args);
+ }
+
+ private final CityMapper cityMapper;
+
+ public SampleFreeMarkerApplication(CityMapper cityMapper) {
+ this.cityMapper = cityMapper;
+ }
+
+ @Override
+ @SuppressWarnings("squid:S106")
+ public void run(String... args) {
+ System.out.println(this.cityMapper.findByState("CA"));
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java
new file mode 100644
index 000000000..afac2ab2a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/domain/City.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2015-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 sample.mybatis.domain;
+
+import java.io.Serializable;
+
+/**
+ * @author Kazuki Shimizu
+ */
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private String country;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ @Override
+ public String toString() {
+ return getId() + "," + getName() + "," + getState() + "," + getCountry();
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java
new file mode 100644
index 000000000..b5221e71d
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/java/sample/mybatis/mapper/CityMapper.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import sample.mybatis.domain.City;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@Mapper
+public interface CityMapper {
+
+ @Select("select id, name, state, country from city where id = <@p name='id'/>")
+ City findById(@Param("id") Long id);
+
+ @Select("/mappers/CityMapper-findByState.ftl")
+ City findByState(@Param("state") String state);
+
+ City findByName(@Param("name") String name);
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties
new file mode 100644
index 000000000..fd28c0490
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Copyright 2015-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.
+#
+
+logging.level.root=WARN
+logging.level.sample.mybatis.mapper=TRACE
+
+mybatis.mapper-locations=classpath*:/mappers/*.xml
+mybatis.type-aliases-package=sample.mybatis.domain
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql
new file mode 100644
index 000000000..4e42e5bc2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/data.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright 2015-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 city (name, state, country) values ('San Francisco', 'CA', 'US');
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl
new file mode 100644
index 000000000..e79b67d8c
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper-findByState.ftl
@@ -0,0 +1,23 @@
+<#--
+
+ Copyright 2015-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
+ id, name, state, country
+from
+ city
+where
+ state = <@p name="state"/>
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml
new file mode 100644
index 000000000..33503e0da
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/mappers/CityMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql
new file mode 100644
index 000000000..b6751f983
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/main/resources/schema.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2015-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.
+--
+
+drop table if exists city;
+
+create table city (id int primary key auto_increment, name varchar, state varchar, country varchar);
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java
new file mode 100644
index 000000000..a081a89fa
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/extensions/CaptureSystemOutput.java
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2015-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 extensions;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.platform.commons.support.ReflectionSupport;
+
+/**
+ * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and
+ * {@code System.err} with expectations supported via Hamcrest matchers.
+ *
+ *
+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit
+ * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method.
+ *
+ *
+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers.
+ *
+ *
+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Sam Brannen
+ */
+ static class OutputCapture {
+
+ private final List> matchers = new ArrayList<>();
+
+ private CaptureOutputStream captureOut;
+
+ private CaptureOutputStream captureErr;
+
+ private ByteArrayOutputStream copy;
+
+ void captureOutput() {
+ this.copy = new ByteArrayOutputStream();
+ this.captureOut = new CaptureOutputStream(System.out, this.copy);
+ this.captureErr = new CaptureOutputStream(System.err, this.copy);
+ System.setOut(new PrintStream(this.captureOut));
+ System.setErr(new PrintStream(this.captureErr));
+ }
+
+ void releaseOutput() {
+ System.setOut(this.captureOut.getOriginal());
+ System.setErr(this.captureErr.getOriginal());
+ this.copy = null;
+ }
+
+ private void flush() {
+ try {
+ this.captureOut.flush();
+ this.captureErr.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ /**
+ * Verify that the captured output is matched by the supplied {@code matcher}.
+ *
+ *
+ * Verification is performed after the test method has executed.
+ *
+ * @param matcher
+ * the matcher
+ */
+ public void expect(Matcher super String> matcher) {
+ this.matchers.add(matcher);
+ }
+
+ /**
+ * Return all captured output to {@code System.out} and {@code System.err} as a single string.
+ */
+ @Override
+ public String toString() {
+ flush();
+ return this.copy.toString();
+ }
+
+ void reset() {
+ this.matchers.clear();
+ this.copy.reset();
+ }
+
+ private static class CaptureOutputStream extends OutputStream {
+
+ private final PrintStream original;
+
+ private final OutputStream copy;
+
+ CaptureOutputStream(PrintStream original, OutputStream copy) {
+ this.original = original;
+ this.copy = copy;
+ }
+
+ PrintStream getOriginal() {
+ return this.original;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ this.copy.write(b);
+ this.original.write(b);
+ this.original.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.copy.write(b, off, len);
+ this.original.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ this.copy.flush();
+ this.original.flush();
+ }
+
+ }
+
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
new file mode 100644
index 000000000..f0c2275e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import extensions.CaptureSystemOutput;
+import extensions.CaptureSystemOutput.OutputCapture;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@CaptureSystemOutput
+@SpringBootTest
+class SampleMybatisApplicationTest {
+
+ @Test
+ void test(OutputCapture outputCapture) {
+ String output = outputCapture.toString();
+ assertThat(output).contains("1,San Francisco,CA,US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java
new file mode 100644
index 000000000..cf4bf63fc
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/CityMapperTest.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.junit.jupiter.api.Test;
+import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
+import sample.mybatis.domain.City;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CityMapper}.
+ *
+ * @author Kazuki Shimizu
+ */
+@MybatisTest
+class CityMapperTest {
+
+ @Autowired
+ private CityMapper cityMapper;
+
+ @Test
+ void findByState() {
+ City city = cityMapper.findByState("CA");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findById() {
+ City city = cityMapper.findById(1L);
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findByName() {
+ City city = cityMapper.findByName("San Francisco");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
new file mode 100644
index 000000000..3f124cebc
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-freemarker/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}.
+ *
+ * This class has role for prevent to run the {@link sample.mybatis.SampleFreeMarkerApplication}. For more detail
+ * information, please refer
+ * Here.
+ *
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class MapperTestApplication {
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml
new file mode 100644
index 000000000..dc8a38327
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/format.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt
new file mode 100644
index 000000000..4ce1777ad
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/license.txt
@@ -0,0 +1,13 @@
+ Copyright ${license.git.copyrightYears} 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/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml
new file mode 100644
index 000000000..b5528ab71
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/pom.xml
@@ -0,0 +1,80 @@
+
+
+
+ 4.0.0
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-samples
+ 2.1.0-SNAPSHOT
+
+ mybatis-spring-boot-sample-thymeleaf
+ jar
+ mybatis-spring-boot-sample-thymeleaf
+
+ org.mybatis.spring.boot.sample.thymeleaf
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.mybatis.scripting
+ mybatis-thymeleaf
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java
new file mode 100644
index 000000000..904ea57b2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/SampleThymeleafApplication.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import sample.mybatis.mapper.CityMapper;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class SampleThymeleafApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleThymeleafApplication.class, args);
+ }
+
+ private final CityMapper cityMapper;
+
+ public SampleThymeleafApplication(CityMapper cityMapper) {
+ this.cityMapper = cityMapper;
+ }
+
+ @Override
+ @SuppressWarnings("squid:S106")
+ public void run(String... args) {
+ System.out.println(this.cityMapper.findByState("CA"));
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java
new file mode 100644
index 000000000..afac2ab2a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/domain/City.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2015-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 sample.mybatis.domain;
+
+import java.io.Serializable;
+
+/**
+ * @author Kazuki Shimizu
+ */
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private String country;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ @Override
+ public String toString() {
+ return getId() + "," + getName() + "," + getState() + "," + getCountry();
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java
new file mode 100644
index 000000000..25876461a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/java/sample/mybatis/mapper/CityMapper.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import sample.mybatis.domain.City;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@Mapper
+public interface CityMapper {
+
+ @Select("select id, name, state, country from city where id = /*[# mb:p='id']*/ 1 /*[/]*/")
+ City findById(@Param("id") Long id);
+
+ @Select("/mappers/CityMapper-findByState.sql")
+ City findByState(@Param("state") String state);
+
+ City findByName(@Param("name") String name);
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties
new file mode 100644
index 000000000..fd28c0490
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Copyright 2015-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.
+#
+
+logging.level.root=WARN
+logging.level.sample.mybatis.mapper=TRACE
+
+mybatis.mapper-locations=classpath*:/mappers/*.xml
+mybatis.type-aliases-package=sample.mybatis.domain
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql
new file mode 100644
index 000000000..4e42e5bc2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/data.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright 2015-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 city (name, state, country) values ('San Francisco', 'CA', 'US');
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql
new file mode 100644
index 000000000..f38250d0a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper-findByState.sql
@@ -0,0 +1,22 @@
+--
+-- Copyright 2015-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
+ id, name, state, country
+from
+ city
+where
+ state = /*[# mb:p="state"]*/ 'CA' /*[/]*/
\ No newline at end of file
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml
new file mode 100644
index 000000000..81ac71d69
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/mappers/CityMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql
new file mode 100644
index 000000000..b6751f983
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/main/resources/schema.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2015-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.
+--
+
+drop table if exists city;
+
+create table city (id int primary key auto_increment, name varchar, state varchar, country varchar);
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java
new file mode 100644
index 000000000..a081a89fa
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/extensions/CaptureSystemOutput.java
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2015-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 extensions;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.platform.commons.support.ReflectionSupport;
+
+/**
+ * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and
+ * {@code System.err} with expectations supported via Hamcrest matchers.
+ *
+ *
+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit
+ * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method.
+ *
+ *
+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers.
+ *
+ *
+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Sam Brannen
+ */
+ static class OutputCapture {
+
+ private final List> matchers = new ArrayList<>();
+
+ private CaptureOutputStream captureOut;
+
+ private CaptureOutputStream captureErr;
+
+ private ByteArrayOutputStream copy;
+
+ void captureOutput() {
+ this.copy = new ByteArrayOutputStream();
+ this.captureOut = new CaptureOutputStream(System.out, this.copy);
+ this.captureErr = new CaptureOutputStream(System.err, this.copy);
+ System.setOut(new PrintStream(this.captureOut));
+ System.setErr(new PrintStream(this.captureErr));
+ }
+
+ void releaseOutput() {
+ System.setOut(this.captureOut.getOriginal());
+ System.setErr(this.captureErr.getOriginal());
+ this.copy = null;
+ }
+
+ private void flush() {
+ try {
+ this.captureOut.flush();
+ this.captureErr.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ /**
+ * Verify that the captured output is matched by the supplied {@code matcher}.
+ *
+ *
+ * Verification is performed after the test method has executed.
+ *
+ * @param matcher
+ * the matcher
+ */
+ public void expect(Matcher super String> matcher) {
+ this.matchers.add(matcher);
+ }
+
+ /**
+ * Return all captured output to {@code System.out} and {@code System.err} as a single string.
+ */
+ @Override
+ public String toString() {
+ flush();
+ return this.copy.toString();
+ }
+
+ void reset() {
+ this.matchers.clear();
+ this.copy.reset();
+ }
+
+ private static class CaptureOutputStream extends OutputStream {
+
+ private final PrintStream original;
+
+ private final OutputStream copy;
+
+ CaptureOutputStream(PrintStream original, OutputStream copy) {
+ this.original = original;
+ this.copy = copy;
+ }
+
+ PrintStream getOriginal() {
+ return this.original;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ this.copy.write(b);
+ this.original.write(b);
+ this.original.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.copy.write(b, off, len);
+ this.original.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ this.copy.flush();
+ this.original.flush();
+ }
+
+ }
+
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
new file mode 100644
index 000000000..f0c2275e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import extensions.CaptureSystemOutput;
+import extensions.CaptureSystemOutput.OutputCapture;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@CaptureSystemOutput
+@SpringBootTest
+class SampleMybatisApplicationTest {
+
+ @Test
+ void test(OutputCapture outputCapture) {
+ String output = outputCapture.toString();
+ assertThat(output).contains("1,San Francisco,CA,US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java
new file mode 100644
index 000000000..cf4bf63fc
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/CityMapperTest.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.junit.jupiter.api.Test;
+import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
+import sample.mybatis.domain.City;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CityMapper}.
+ *
+ * @author Kazuki Shimizu
+ */
+@MybatisTest
+class CityMapperTest {
+
+ @Autowired
+ private CityMapper cityMapper;
+
+ @Test
+ void findByState() {
+ City city = cityMapper.findByState("CA");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findById() {
+ City city = cityMapper.findById(1L);
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findByName() {
+ City city = cityMapper.findByName("San Francisco");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
new file mode 100644
index 000000000..aad1d2bff
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-thymeleaf/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}.
+ *
+ * This class has role for prevent to run the {@link sample.mybatis.SampleThymeleafApplication}. For more detail
+ * information, please refer
+ * Here.
+ *
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class MapperTestApplication {
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml
new file mode 100644
index 000000000..dc8a38327
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/format.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt
new file mode 100644
index 000000000..4ce1777ad
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/license.txt
@@ -0,0 +1,13 @@
+ Copyright ${license.git.copyrightYears} 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/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml
new file mode 100644
index 000000000..561aad120
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/pom.xml
@@ -0,0 +1,81 @@
+
+
+
+ 4.0.0
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-samples
+ 2.1.0-SNAPSHOT
+
+ mybatis-spring-boot-sample-velocity-legacy
+ jar
+ mybatis-spring-boot-sample-velocity-legacy
+
+ org.mybatis.spring.boot.sample.legacyvelocity
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.mybatis.scripting
+ mybatis-velocity
+ 2.0
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java
new file mode 100644
index 000000000..9a3abbcb7
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/SampleVelocityApplication.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import sample.mybatis.mapper.CityMapper;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class SampleVelocityApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleVelocityApplication.class, args);
+ }
+
+ private final CityMapper cityMapper;
+
+ public SampleVelocityApplication(CityMapper cityMapper) {
+ this.cityMapper = cityMapper;
+ }
+
+ @Override
+ @SuppressWarnings("squid:S106")
+ public void run(String... args) {
+ System.out.println(this.cityMapper.findById(1L));
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java
new file mode 100644
index 000000000..afac2ab2a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/domain/City.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2015-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 sample.mybatis.domain;
+
+import java.io.Serializable;
+
+/**
+ * @author Kazuki Shimizu
+ */
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private String country;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ @Override
+ public String toString() {
+ return getId() + "," + getName() + "," + getState() + "," + getCountry();
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java
new file mode 100644
index 000000000..befa7d41f
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/java/sample/mybatis/mapper/CityMapper.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import sample.mybatis.domain.City;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@Mapper
+public interface CityMapper {
+
+ @Select("select id, name, state, country from city where id = @{id}")
+ City findById(@Param("id") Long id);
+
+ // TODO Does not support template file yet
+ // @Select("/mappers/CityMapper-findByState.vm")
+ // @Select("#parse('/mappers/CityMapper-findByState.vm')")
+ City findByState(@Param("state") String state);
+
+ City findByName(@Param("name") String name);
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties
new file mode 100644
index 000000000..fd28c0490
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Copyright 2015-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.
+#
+
+logging.level.root=WARN
+logging.level.sample.mybatis.mapper=TRACE
+
+mybatis.mapper-locations=classpath*:/mappers/*.xml
+mybatis.type-aliases-package=sample.mybatis.domain
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql
new file mode 100644
index 000000000..4e42e5bc2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/data.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright 2015-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 city (name, state, country) values ('San Francisco', 'CA', 'US');
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm
new file mode 100644
index 000000000..d7fcb1628
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper-findByState.vm
@@ -0,0 +1,22 @@
+#*
+ * Copyright 2015-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.
+ *#
+## Does not support template file yet
+select
+ id, name, state, country
+from
+ city
+where
+ state = @{state}
\ No newline at end of file
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml
new file mode 100644
index 000000000..169b05264
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/mappers/CityMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql
new file mode 100644
index 000000000..b6751f983
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/main/resources/schema.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2015-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.
+--
+
+drop table if exists city;
+
+create table city (id int primary key auto_increment, name varchar, state varchar, country varchar);
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java
new file mode 100644
index 000000000..a081a89fa
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/extensions/CaptureSystemOutput.java
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2015-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 extensions;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.platform.commons.support.ReflectionSupport;
+
+/**
+ * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and
+ * {@code System.err} with expectations supported via Hamcrest matchers.
+ *
+ *
+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit
+ * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method.
+ *
+ *
+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers.
+ *
+ *
+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Sam Brannen
+ */
+ static class OutputCapture {
+
+ private final List> matchers = new ArrayList<>();
+
+ private CaptureOutputStream captureOut;
+
+ private CaptureOutputStream captureErr;
+
+ private ByteArrayOutputStream copy;
+
+ void captureOutput() {
+ this.copy = new ByteArrayOutputStream();
+ this.captureOut = new CaptureOutputStream(System.out, this.copy);
+ this.captureErr = new CaptureOutputStream(System.err, this.copy);
+ System.setOut(new PrintStream(this.captureOut));
+ System.setErr(new PrintStream(this.captureErr));
+ }
+
+ void releaseOutput() {
+ System.setOut(this.captureOut.getOriginal());
+ System.setErr(this.captureErr.getOriginal());
+ this.copy = null;
+ }
+
+ private void flush() {
+ try {
+ this.captureOut.flush();
+ this.captureErr.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ /**
+ * Verify that the captured output is matched by the supplied {@code matcher}.
+ *
+ *
+ * Verification is performed after the test method has executed.
+ *
+ * @param matcher
+ * the matcher
+ */
+ public void expect(Matcher super String> matcher) {
+ this.matchers.add(matcher);
+ }
+
+ /**
+ * Return all captured output to {@code System.out} and {@code System.err} as a single string.
+ */
+ @Override
+ public String toString() {
+ flush();
+ return this.copy.toString();
+ }
+
+ void reset() {
+ this.matchers.clear();
+ this.copy.reset();
+ }
+
+ private static class CaptureOutputStream extends OutputStream {
+
+ private final PrintStream original;
+
+ private final OutputStream copy;
+
+ CaptureOutputStream(PrintStream original, OutputStream copy) {
+ this.original = original;
+ this.copy = copy;
+ }
+
+ PrintStream getOriginal() {
+ return this.original;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ this.copy.write(b);
+ this.original.write(b);
+ this.original.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.copy.write(b, off, len);
+ this.original.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ this.copy.flush();
+ this.original.flush();
+ }
+
+ }
+
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
new file mode 100644
index 000000000..f0c2275e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import extensions.CaptureSystemOutput;
+import extensions.CaptureSystemOutput.OutputCapture;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@CaptureSystemOutput
+@SpringBootTest
+class SampleMybatisApplicationTest {
+
+ @Test
+ void test(OutputCapture outputCapture) {
+ String output = outputCapture.toString();
+ assertThat(output).contains("1,San Francisco,CA,US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java
new file mode 100644
index 000000000..9561ba8e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/CityMapperTest.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
+import sample.mybatis.domain.City;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CityMapper}.
+ *
+ * @author Kazuki Shimizu
+ */
+@MybatisTest
+class CityMapperTest {
+
+ @Autowired
+ private CityMapper cityMapper;
+
+ @Test
+ @Disabled("Does not support template file yet")
+ void findByState() {
+ City city = cityMapper.findByState("CA");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findById() {
+ City city = cityMapper.findById(1L);
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findByName() {
+ City city = cityMapper.findByName("San Francisco");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
new file mode 100644
index 000000000..cc515fef1
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity-legacy/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}.
+ *
+ * This class has role for prevent to run the {@link sample.mybatis.SampleVelocityApplication}. For more detail
+ * information, please refer
+ * Here.
+ *
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class MapperTestApplication {
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml
new file mode 100644
index 000000000..dc8a38327
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/format.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt
new file mode 100644
index 000000000..4ce1777ad
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/license.txt
@@ -0,0 +1,13 @@
+ Copyright ${license.git.copyrightYears} 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/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml
new file mode 100644
index 000000000..5c736cf87
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/pom.xml
@@ -0,0 +1,80 @@
+
+
+
+ 4.0.0
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-samples
+ 2.1.0-SNAPSHOT
+
+ mybatis-spring-boot-sample-velocity
+ jar
+ mybatis-spring-boot-sample-velocity
+
+ org.mybatis.spring.boot.sample.velocity
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+
+
+ org.mybatis.scripting
+ mybatis-velocity
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java
new file mode 100644
index 000000000..9a3abbcb7
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/SampleVelocityApplication.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import sample.mybatis.mapper.CityMapper;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class SampleVelocityApplication implements CommandLineRunner {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleVelocityApplication.class, args);
+ }
+
+ private final CityMapper cityMapper;
+
+ public SampleVelocityApplication(CityMapper cityMapper) {
+ this.cityMapper = cityMapper;
+ }
+
+ @Override
+ @SuppressWarnings("squid:S106")
+ public void run(String... args) {
+ System.out.println(this.cityMapper.findById(1L));
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java
new file mode 100644
index 000000000..afac2ab2a
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/domain/City.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2015-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 sample.mybatis.domain;
+
+import java.io.Serializable;
+
+/**
+ * @author Kazuki Shimizu
+ */
+public class City implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Long id;
+
+ private String name;
+
+ private String state;
+
+ private String country;
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ @Override
+ public String toString() {
+ return getId() + "," + getName() + "," + getState() + "," + getCountry();
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java
new file mode 100644
index 000000000..befa7d41f
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/java/sample/mybatis/mapper/CityMapper.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import sample.mybatis.domain.City;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@Mapper
+public interface CityMapper {
+
+ @Select("select id, name, state, country from city where id = @{id}")
+ City findById(@Param("id") Long id);
+
+ // TODO Does not support template file yet
+ // @Select("/mappers/CityMapper-findByState.vm")
+ // @Select("#parse('/mappers/CityMapper-findByState.vm')")
+ City findByState(@Param("state") String state);
+
+ City findByName(@Param("name") String name);
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties
new file mode 100644
index 000000000..fd28c0490
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Copyright 2015-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.
+#
+
+logging.level.root=WARN
+logging.level.sample.mybatis.mapper=TRACE
+
+mybatis.mapper-locations=classpath*:/mappers/*.xml
+mybatis.type-aliases-package=sample.mybatis.domain
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql
new file mode 100644
index 000000000..4e42e5bc2
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/data.sql
@@ -0,0 +1,17 @@
+--
+-- Copyright 2015-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 city (name, state, country) values ('San Francisco', 'CA', 'US');
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm
new file mode 100644
index 000000000..d7fcb1628
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper-findByState.vm
@@ -0,0 +1,22 @@
+#*
+ * Copyright 2015-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.
+ *#
+## Does not support template file yet
+select
+ id, name, state, country
+from
+ city
+where
+ state = @{state}
\ No newline at end of file
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml
new file mode 100644
index 000000000..169b05264
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/mappers/CityMapper.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql
new file mode 100644
index 000000000..b6751f983
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/main/resources/schema.sql
@@ -0,0 +1,19 @@
+--
+-- Copyright 2015-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.
+--
+
+drop table if exists city;
+
+create table city (id int primary key auto_increment, name varchar, state varchar, country varchar);
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java
new file mode 100644
index 000000000..a081a89fa
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/extensions/CaptureSystemOutput.java
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2015-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 extensions;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hamcrest.Matcher;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.platform.commons.support.ReflectionSupport;
+
+/**
+ * {@code @CaptureSystemOutput} is a JUnit JUpiter extension for capturing output to {@code System.out} and
+ * {@code System.err} with expectations supported via Hamcrest matchers.
+ *
+ *
+ * To obtain an instance of {@code OutputCapture}, declare a parameter of type {@code OutputCapture} in a JUnit
+ * Jupiter {@code @Test}, {@code @BeforeEach}, or {@code @AfterEach} method.
+ *
+ *
+ * {@linkplain #expect Expectations} are supported via Hamcrest matchers.
+ *
+ *
+ * To obtain all output to {@code System.out} and {@code System.err}, simply invoke {@link #toString()}.
+ *
+ * @author Phillip Webb
+ * @author Andy Wilkinson
+ * @author Sam Brannen
+ */
+ static class OutputCapture {
+
+ private final List> matchers = new ArrayList<>();
+
+ private CaptureOutputStream captureOut;
+
+ private CaptureOutputStream captureErr;
+
+ private ByteArrayOutputStream copy;
+
+ void captureOutput() {
+ this.copy = new ByteArrayOutputStream();
+ this.captureOut = new CaptureOutputStream(System.out, this.copy);
+ this.captureErr = new CaptureOutputStream(System.err, this.copy);
+ System.setOut(new PrintStream(this.captureOut));
+ System.setErr(new PrintStream(this.captureErr));
+ }
+
+ void releaseOutput() {
+ System.setOut(this.captureOut.getOriginal());
+ System.setErr(this.captureErr.getOriginal());
+ this.copy = null;
+ }
+
+ private void flush() {
+ try {
+ this.captureOut.flush();
+ this.captureErr.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ /**
+ * Verify that the captured output is matched by the supplied {@code matcher}.
+ *
+ *
+ * Verification is performed after the test method has executed.
+ *
+ * @param matcher
+ * the matcher
+ */
+ public void expect(Matcher super String> matcher) {
+ this.matchers.add(matcher);
+ }
+
+ /**
+ * Return all captured output to {@code System.out} and {@code System.err} as a single string.
+ */
+ @Override
+ public String toString() {
+ flush();
+ return this.copy.toString();
+ }
+
+ void reset() {
+ this.matchers.clear();
+ this.copy.reset();
+ }
+
+ private static class CaptureOutputStream extends OutputStream {
+
+ private final PrintStream original;
+
+ private final OutputStream copy;
+
+ CaptureOutputStream(PrintStream original, OutputStream copy) {
+ this.original = original;
+ this.copy = copy;
+ }
+
+ PrintStream getOriginal() {
+ return this.original;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ this.copy.write(b);
+ this.original.write(b);
+ this.original.flush();
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ this.copy.write(b, off, len);
+ this.original.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ this.copy.flush();
+ this.original.flush();
+ }
+
+ }
+
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
new file mode 100644
index 000000000..f0c2275e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/SampleMybatisApplicationTest.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2015-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 sample.mybatis;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import extensions.CaptureSystemOutput;
+import extensions.CaptureSystemOutput.OutputCapture;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Kazuki Shimizu
+ */
+@CaptureSystemOutput
+@SpringBootTest
+class SampleMybatisApplicationTest {
+
+ @Test
+ void test(OutputCapture outputCapture) {
+ String output = outputCapture.toString();
+ assertThat(output).contains("1,San Francisco,CA,US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java
new file mode 100644
index 000000000..9561ba8e5
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/CityMapperTest.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
+import sample.mybatis.domain.City;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CityMapper}.
+ *
+ * @author Kazuki Shimizu
+ */
+@MybatisTest
+class CityMapperTest {
+
+ @Autowired
+ private CityMapper cityMapper;
+
+ @Test
+ @Disabled("Does not support template file yet")
+ void findByState() {
+ City city = cityMapper.findByState("CA");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findById() {
+ City city = cityMapper.findById(1L);
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+ @Test
+ void findByName() {
+ City city = cityMapper.findByName("San Francisco");
+ assertThat(city.getId()).isEqualTo(1);
+ assertThat(city.getName()).isEqualTo("San Francisco");
+ assertThat(city.getState()).isEqualTo("CA");
+ assertThat(city.getCountry()).isEqualTo("US");
+ }
+
+}
diff --git a/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
new file mode 100644
index 000000000..cc515fef1
--- /dev/null
+++ b/mybatis-spring-boot-samples/mybatis-spring-boot-sample-velocity/src/test/java/sample/mybatis/mapper/MapperTestApplication.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 2015-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 sample.mybatis.mapper;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * The Spring Boot Application for testing {@link org.mybatis.spring.boot.test.autoconfigure.MybatisTest @MybatisTest}.
+ *
+ * This class has role for prevent to run the {@link sample.mybatis.SampleVelocityApplication}. For more detail
+ * information, please refer
+ * Here.
+ *
+ * @author Kazuki Shimizu
+ */
+@SpringBootApplication
+public class MapperTestApplication {
+
+}
diff --git a/mybatis-spring-boot-samples/pom.xml b/mybatis-spring-boot-samples/pom.xml
index 0cf29c616..826936514 100644
--- a/mybatis-spring-boot-samples/pom.xml
+++ b/mybatis-spring-boot-samples/pom.xml
@@ -29,5 +29,10 @@
mybatis-spring-boot-sample-annotationmybatis-spring-boot-sample-xml
+ mybatis-spring-boot-sample-thymeleaf
+ mybatis-spring-boot-sample-freemarker
+ mybatis-spring-boot-sample-freemarker-legacy
+ mybatis-spring-boot-sample-velocity
+ mybatis-spring-boot-sample-velocity-legacy