Skip to content

Commit

Permalink
Merge pull request #331 from kazuki43zoo/gh-300
Browse files Browse the repository at this point in the history
Support auto-configure LanguageDriver provided by MyBatis's sub module
  • Loading branch information
kazuki43zoo authored May 2, 2019
2 parents 134cd12 + ac40316 commit 31dc060
Show file tree
Hide file tree
Showing 9 changed files with 441 additions and 6 deletions.
15 changes: 15 additions & 0 deletions mybatis-spring-boot-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@
<artifactId>slf4j-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis.scripting</groupId>
<artifactId>mybatis-freemarker</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis.scripting</groupId>
<artifactId>mybatis-velocity</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mybatis.scripting</groupId>
<artifactId>mybatis-thymeleaf</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@
*/
package org.mybatis.spring.boot.autoconfigure;

import java.beans.PropertyDescriptor;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.sql.DataSource;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
Expand Down Expand Up @@ -78,7 +82,7 @@
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class })
public class MybatisAutoConfiguration implements InitializingBean {

private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
Expand All @@ -89,19 +93,22 @@ public class MybatisAutoConfiguration implements InitializingBean {

private final TypeHandler[] typeHandlers;

private final LanguageDriver[] languageDrivers;

private final ResourceLoader resourceLoader;

private final DatabaseIdProvider databaseIdProvider;

private final List<ConfigurationCustomizer> configurationCustomizers;

public MybatisAutoConfiguration(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<TypeHandler[]> typeHandlersProvider, ResourceLoader resourceLoader,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ObjectProvider<TypeHandler[]> typeHandlersProvider, ObjectProvider<LanguageDriver[]> languageDriversProvider,
ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
this.properties = properties;
this.interceptors = interceptorsProvider.getIfAvailable();
this.typeHandlers = typeHandlersProvider.getIfAvailable();
this.languageDrivers = languageDriversProvider.getIfAvailable();
this.resourceLoader = resourceLoader;
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
Expand Down Expand Up @@ -154,6 +161,21 @@ public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Excepti
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
Set<String> factoryPropertyNames = Stream
.of(new BeanWrapperImpl(SqlSessionFactoryBean.class).getPropertyDescriptors()).map(PropertyDescriptor::getName)
.collect(Collectors.toSet());
Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
// Need to mybatis-spring 2.0.2+
factory.setScriptingLanguageDrivers(this.languageDrivers);
if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
defaultLanguageDriver = this.languageDrivers[0].getClass();
}
}
if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
// Need to mybatis-spring 2.0.2+
factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
}

return factory.getObject();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* 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 org.mybatis.spring.boot.autoconfigure;

import org.apache.ibatis.scripting.LanguageDriver;
import org.mybatis.scripting.freemarker.FreeMarkerLanguageDriver;
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriver;
import org.mybatis.scripting.thymeleaf.ThymeleafLanguageDriverConfig;
import org.mybatis.scripting.velocity.Driver;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* {@link EnableAutoConfiguration Auto-Configuration} for MyBatis's scripting language drivers.
*
* @author Kazuki Shimizu
* @since 2.1.0
*/
@Configuration
@ConditionalOnClass(LanguageDriver.class)
public class MybatisLanguageDriverAutoConfiguration {

@Configuration
@ConditionalOnClass(FreeMarkerLanguageDriver.class)
static class FreeMarkerConfiguration {
@Bean
@ConditionalOnMissingBean
FreeMarkerLanguageDriver freeMarkerLanguageDriver() {
return new FreeMarkerLanguageDriver();
}
}

@Configuration
@ConditionalOnClass(Driver.class)
static class VelocityConfiguration {
@Bean
@ConditionalOnMissingBean
Driver velocityLanguageDriver() {
return new Driver();
}
}

@Configuration
@ConditionalOnClass(ThymeleafLanguageDriver.class)
static class ThymeleafConfiguration {
@Bean
@ConditionalOnMissingBean
ThymeleafLanguageDriver thymeleafLanguageDriver(ObjectProvider<ThymeleafLanguageDriverConfig> configProvider) {
return new ThymeleafLanguageDriver(configProvider.getIfAvailable(ThymeleafLanguageDriverConfig::newInstance));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Properties;
import java.util.stream.Stream;

import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;

Expand Down Expand Up @@ -78,6 +79,11 @@ public class MybatisProperties {
*/
private ExecutorType executorType;

/**
* The default scripting language driver class. (Available when use together with mybatis-spring 2.0.2+)
*/
private Class<? extends LanguageDriver> defaultScriptingLanguageDriver;

/**
* Externalized properties for MyBatis configuration.
*/
Expand Down Expand Up @@ -158,6 +164,20 @@ public void setExecutorType(ExecutorType executorType) {
this.executorType = executorType;
}

/**
* @since 2.1.0
*/
public Class<? extends LanguageDriver> getDefaultScriptingLanguageDriver() {
return defaultScriptingLanguageDriver;
}

/**
* @since 2.1.0
*/
public void setDefaultScriptingLanguageDriver(Class<? extends LanguageDriver> defaultScriptingLanguageDriver) {
this.defaultScriptingLanguageDriver = defaultScriptingLanguageDriver;
}

/**
* @since 1.2.0
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration,\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
66 changes: 63 additions & 3 deletions mybatis-spring-boot-autoconfigure/src/site/xdoc/index.xml.vm
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<tbody>
<tr>
<td><b>2.1</b></td>
<td>2.0 or higher</td>
<td>2.0 or higher (need 2.0.2+ for enable all features)</td>
<td>2.1 or higher</td>
<td>8 or higher</td>
</tr>
Expand Down Expand Up @@ -288,6 +288,15 @@ public class CityDao {
Executor type: <code>SIMPLE</code>, <code>REUSE</code>, <code>BATCH</code>.
</td>
</tr>
<tr>
<td>
<code>default-scripting-language-driver</code>
</td>
<td>
The default scripting language driver class.
This feature requires to use together with mybatis-spring 2.0.2+.
</td>
</tr>
<tr>
<td>
<code>configuration-properties</code>
Expand All @@ -303,7 +312,7 @@ public class CityDao {
</td>
<td>
Whether enable lazy initialization of mapper bean. Set <code>true</code> to enable lazy initialization.
This feature requires to use together with mybatis-spring 2.0.2+. (Available since 2.1.0)
This feature requires to use together with mybatis-spring 2.0.2+.
</td>
</tr>
<tr>
Expand Down Expand Up @@ -398,10 +407,61 @@ public SqlSessionFactory masterSqlSessionFactory() throws Exception {

<ul>
<li><a href="http://www.mybatis.org/mybatis-3/configuration.html#plugins">Interceptor</a></li>
<li><a href="http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers">TypeHandler(Available since 2.1.0)</a></li>
<li><a href="http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers">TypeHandler</a></li>
<li><a href="http://www.mybatis.org/mybatis-3/dynamic-sql.html#Pluggable_Scripting_Languages_For_Dynamic_SQL">LanguageDriver</a>(Requires to use together with mybatis-spring 2.0.2+)</li>
<li><a href="http://www.mybatis.org/mybatis-3/configuration.html#databaseIdProvider">DatabaseIdProvider</a></li>
</ul>

<source><![CDATA[
// @Configuration class
@Bean
MyInterceptor myInterceptor() {
return MyInterceptor();
}
@Bean
MyTypeHandler myTypeHandler() {
return MyTypeHandler();
}
@Bean
MyLanguageDriver myLanguageDriver() {
return MyLanguageDriver();
}
@Bean
VendorDatabaseIdProvider databaseIdProvider() {
VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
properties.put("SQL Server", "sqlserver");
properties.put("DB2", "db2");
properties.put("H2", "h2");
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
]]></source>

<p>
<span class="label important">NOTE</span> If detected <code>LangaugeDriver</code>'s count is one,
it set to default scripting language automatically.
</p>

</subsection>

<subsection name="Customization for ThymeleafLanguageDriver">

<p>
If you want to customize the ThymeleafLanguageDriver creating by auto-configure,
please register bean of <code>ThymeleafLanguageDriverConfig</code> as follow:
</p>

<source><![CDATA[
// @Configuration class
@Bean
ThymeleafLanguageDriverConfig thymeleafLanguageDriverConfig() {
return ThymeleafLanguageDriverConfig.newInstance(c -> {
// ... customization code
});
}
]]></source>

</subsection>

<subsection name="Running Samples">
Expand Down
Loading

0 comments on commit 31dc060

Please sign in to comment.