Skip to content

Commit 57ed37b

Browse files
committed
Support global configuration for applying sql provider type when omit on annotation
1 parent cd34da4 commit 57ed37b

File tree

6 files changed

+104
-2
lines changed

6 files changed

+104
-2
lines changed

src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public ProviderSqlSource(Configuration configuration, Annotation provider, Class
100100
this.mapperMethod = mapperMethod;
101101
Lang lang = mapperMethod == null ? null : mapperMethod.getAnnotation(Lang.class);
102102
this.languageDriver = configuration.getLanguageDriver(lang == null ? null : lang.value());
103-
this.providerType = getProviderType(provider, mapperMethod);
103+
this.providerType = getProviderType(configuration, provider, mapperMethod);
104104
candidateProviderMethodName = (String) provider.annotationType().getMethod("method").invoke(provider);
105105

106106
if (candidateProviderMethodName.length() == 0 && ProviderMethodResolver.class.isAssignableFrom(this.providerType)) {
@@ -235,11 +235,14 @@ private String invokeProviderMethod(Object... args) throws Exception {
235235
return sql != null ? sql.toString() : null;
236236
}
237237

238-
private Class<?> getProviderType(Annotation providerAnnotation, Method mapperMethod)
238+
private Class<?> getProviderType(Configuration configuration, Annotation providerAnnotation, Method mapperMethod)
239239
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
240240
Class<?> type = (Class<?>) providerAnnotation.annotationType().getMethod("type").invoke(providerAnnotation);
241241
Class<?> value = (Class<?>) providerAnnotation.annotationType().getMethod("value").invoke(providerAnnotation);
242242
if (value == void.class && type == void.class) {
243+
if (configuration.getDefaultSqlProviderType() != null) {
244+
return configuration.getDefaultSqlProviderType();
245+
}
243246
throw new BuilderException("Please specify either 'value' or 'type' attribute of @"
244247
+ providerAnnotation.annotationType().getSimpleName()
245248
+ " at the '" + mapperMethod.toString() + "'.");

src/main/java/org/apache/ibatis/builder/xml/XMLConfigBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ private void settingsElement(Properties props) {
269269
configuration.setLogPrefix(props.getProperty("logPrefix"));
270270
configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
271271
configuration.setShrinkWhitespacesInSql(booleanValueOf(props.getProperty("shrinkWhitespacesInSql"), false));
272+
configuration.setDefaultSqlProviderType(resolveClass(props.getProperty("defaultSqlProviderType")));
272273
}
273274

274275
private void environmentsElement(XNode context) throws Exception {

src/main/java/org/apache/ibatis/session/Configuration.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public class Configuration {
118118
protected String logPrefix;
119119
protected Class<? extends Log> logImpl;
120120
protected Class<? extends VFS> vfsImpl;
121+
protected Class<?> defaultSqlProviderType;
121122
protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
122123
protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
123124
protected Set<String> lazyLoadTriggerMethods = new HashSet<>(Arrays.asList("equals", "clone", "hashCode", "toString"));
@@ -243,6 +244,27 @@ public void setVfsImpl(Class<? extends VFS> vfsImpl) {
243244
}
244245
}
245246

247+
/**
248+
* GEt an applying type when omit a type on sql provider annotation(e.g. {@link org.apache.ibatis.annotations.SelectProvider}).
249+
*
250+
* @return the default type for sql provider annotation
251+
* @since 3.5.6
252+
*/
253+
public Class<?> getDefaultSqlProviderType() {
254+
return defaultSqlProviderType;
255+
}
256+
257+
/**
258+
* Sets an applying type when omit a type on sql provider annotation(e.g. {@link org.apache.ibatis.annotations.SelectProvider}).
259+
*
260+
* @param defaultSqlProviderType
261+
* the default type for sql provider annotation
262+
* @since 3.5.6
263+
*/
264+
public void setDefaultSqlProviderType(Class<?> defaultSqlProviderType) {
265+
this.defaultSqlProviderType = defaultSqlProviderType;
266+
}
267+
246268
public boolean isCallSettersOnNulls() {
247269
return callSettersOnNulls;
248270
}

src/test/java/org/apache/ibatis/builder/CustomizedSettingsMapperConfig.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<setting name="configurationFactory" value="java.lang.String"/>
5656
<setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
5757
<setting name="shrinkWhitespacesInSql" value="true"/>
58+
<setting name="defaultSqlProviderType" value="org.apache.ibatis.builder.XmlConfigBuilderTest$MySqlProvider"/>
5859
</settings>
5960

6061
<typeAliases>

src/test/java/org/apache/ibatis/builder/XmlConfigBuilderTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ void shouldSuccessfullyLoadMinimalXMLConfigFile() throws Exception {
101101
assertNull(config.getConfigurationFactory());
102102
assertThat(config.getTypeHandlerRegistry().getTypeHandler(RoundingMode.class)).isInstanceOf(EnumTypeHandler.class);
103103
assertThat(config.isShrinkWhitespacesInSql()).isFalse();
104+
assertThat(config.getDefaultSqlProviderType()).isNull();
104105
}
105106
}
106107

@@ -196,6 +197,7 @@ void shouldSuccessfullyLoadXMLConfigFile() throws Exception {
196197
assertThat(config.getVfsImpl().getName()).isEqualTo(JBoss6VFS.class.getName());
197198
assertThat(config.getConfigurationFactory().getName()).isEqualTo(String.class.getName());
198199
assertThat(config.isShrinkWhitespacesInSql()).isTrue();
200+
assertThat(config.getDefaultSqlProviderType().getName()).isEqualTo(MySqlProvider.class.getName());
199201

200202
assertThat(config.getTypeAliasRegistry().getTypeAliases().get("blogauthor")).isEqualTo(Author.class);
201203
assertThat(config.getTypeAliasRegistry().getTypeAliases().get("blog")).isEqualTo(Blog.class);
@@ -304,4 +306,11 @@ void propertiesSpecifyResourceAndUrlAtSameTime() {
304306
.hasMessageContaining("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other.");
305307
}
306308

309+
static class MySqlProvider {
310+
@SuppressWarnings("unused")
311+
public static String provideSql() {
312+
return "SELECT 1";
313+
}
314+
}
315+
307316
}

src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
import java.util.Map;
3131

3232
import org.apache.ibatis.BaseDataTest;
33+
import org.apache.ibatis.annotations.InsertProvider;
3334
import org.apache.ibatis.annotations.DeleteProvider;
3435
import org.apache.ibatis.annotations.Param;
3536
import org.apache.ibatis.annotations.SelectProvider;
37+
import org.apache.ibatis.annotations.UpdateProvider;
3638
import org.apache.ibatis.binding.MapperMethod;
3739
import org.apache.ibatis.builder.BuilderException;
3840
import org.apache.ibatis.builder.annotation.ProviderContext;
@@ -661,6 +663,70 @@ void keepBackwardCompatibilityOnDeprecatedConstructorWithAnnotation() throws NoS
661663
assertEquals("SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS", sqlSource.getBoundSql(null).getSql());
662664
}
663665

666+
@Test
667+
void omitTypeWhenSpecifyDefaultType() throws NoSuchMethodException {
668+
Class<?> mapperType = DefaultSqlProviderMapper.class;
669+
Configuration configuration = new Configuration();
670+
configuration.setDefaultSqlProviderType(DefaultSqlProviderMapper.SqlProvider.class);
671+
{
672+
Method mapperMethod = mapperType.getMethod("select", int.class);
673+
String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(SelectProvider.class), mapperType,
674+
mapperMethod).getBoundSql(1).getSql();
675+
assertEquals("select name from foo where id = ?", sql);
676+
}
677+
{
678+
Method mapperMethod = mapperType.getMethod("insert", String.class);
679+
String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(InsertProvider.class), mapperType,
680+
mapperMethod).getBoundSql("Taro").getSql();
681+
assertEquals("insert into foo (name) values(?)", sql);
682+
}
683+
{
684+
Method mapperMethod = mapperType.getMethod("update", int.class, String.class);
685+
String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(UpdateProvider.class), mapperType,
686+
mapperMethod).getBoundSql(Collections.emptyMap() ).getSql();
687+
assertEquals("update foo set name = ? where id = ?", sql);
688+
}
689+
{
690+
Method mapperMethod = mapperType.getMethod("delete", int.class);
691+
String sql = new ProviderSqlSource(configuration, mapperMethod.getAnnotation(DeleteProvider.class), mapperType,
692+
mapperMethod).getBoundSql(Collections.emptyMap() ).getSql();
693+
assertEquals("delete from foo where id = ?", sql);
694+
}
695+
}
696+
697+
public interface DefaultSqlProviderMapper {
698+
699+
@SelectProvider
700+
String select(int id);
701+
702+
@InsertProvider
703+
void insert(String name);
704+
705+
@UpdateProvider
706+
void update(int id, String name);
707+
708+
@DeleteProvider
709+
void delete(int id);
710+
711+
class SqlProvider {
712+
713+
public static String provideSql(ProviderContext c) {
714+
switch (c.getMapperMethod().getName()) {
715+
case "select" :
716+
return "select name from foo where id = #{id}";
717+
case "insert" :
718+
return "insert into foo (name) values(#{name})";
719+
case "update" :
720+
return "update foo set name = #{name} where id = #{id}";
721+
default:
722+
return "delete from foo where id = #{id}";
723+
}
724+
}
725+
726+
}
727+
728+
}
729+
664730
public interface ErrorMapper {
665731
@SelectProvider(type = ErrorSqlBuilder.class, method = "methodNotFound")
666732
void methodNotFound();

0 commit comments

Comments
 (0)