Skip to content

Commit 28b3f89

Browse files
authored
Merge pull request #1951 from kazuki43zoo/support-defaultSqlProviderType
Support global configuration for applying sql provider type when omit on annotation Fixes gh-1951
2 parents 4917d53 + 9df34f5 commit 28b3f89

File tree

16 files changed

+313
-7
lines changed

16 files changed

+313
-7
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+
* Gets 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/site/es/xdoc/configuration.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,22 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
561561
false
562562
</td>
563563
</tr>
564+
<tr>
565+
<td>
566+
defaultSqlProviderType
567+
</td>
568+
<td>
569+
Specifies an sql provider class that holds provider method (Since 3.5.6).
570+
This class apply to the <code>type</code>(or <code>value</code>) attribute on sql provider annotation(e.g. <code>@SelectProvider</code>),
571+
when these attribute was omitted.
572+
</td>
573+
<td>
574+
A type alias or fully qualified class name
575+
</td>
576+
<td>
577+
Not set
578+
</td>
579+
</tr>
564580
</tbody>
565581
</table>
566582
<p>

src/site/es/xdoc/java-api.xml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ void rollback(boolean force)</source>
480480
via the <code>ProviderContext</code>(available since MyBatis 3.4.5 or later) as method argument.(In MyBatis 3.4 or later, it's allow multiple parameters)
481481
Atributos: value, type y method.
482482
El atributo value y type es el nombre completamente cualificado de una clase
483-
(The <code>type</code> attribute is alias for <code>value</code>, you must be specify either one).
483+
(The <code>type</code> attribute is alias for <code>value</code>, you must be specify either one.
484+
But both attributes can be omit when specify the <code>defaultSqlProviderType</code> as global configuration).
484485
El method es el nombre un método de dicha clase
485486
(Since 3.5.1, you can omit <code>method</code> attribute, the MyBatis will resolve a target method via the
486487
<code>ProviderMethodResolver</code> interface.
@@ -635,6 +636,29 @@ class UserSqlProvider implements ProviderMethodResolver {
635636
}
636637
}]]></source>
637638

639+
<p>This example shows usage that share an sql provider class to all mapper methods using global configuration(Available since 3.5.6):</p>
640+
<source><![CDATA[
641+
Configuration configuration = new Configuration();
642+
configuration.setDefaultSqlProviderType(TemplateFilePathProvider.class); // Specify an sql provider class for sharing on all mapper methods
643+
// ...]]></source>
644+
<source><![CDATA[
645+
// Can omit the type/value attribute on sql provider annotation
646+
// If omit it, the MyBatis apply the class that specified on defaultSqlProviderType.
647+
public interface UserMapper {
648+
649+
@SelectProvider // Same with @SelectProvider(TemplateFilePathProvider.class)
650+
User findUser(int id);
651+
652+
@InsertProvider // Same with @InsertProvider(TemplateFilePathProvider.class)
653+
void createUser(User user);
654+
655+
@UpdateProvider // Same with @UpdateProvider(TemplateFilePathProvider.class)
656+
void updateUser(User user);
657+
658+
@DeleteProvider // Same with @DeleteProvider(TemplateFilePathProvider.class)
659+
void deleteUser(int id);
660+
}]]></source>
661+
638662
<p>This example shows usage the default implementation of <code>ProviderMethodResolver</code>(available since MyBatis 3.5.1 or later):</p>
639663
<source><![CDATA[@SelectProvider(UserSqlProvider.class)
640664
List<User> getUsersByName(String name);

src/site/ja/xdoc/configuration.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,21 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
586586
false
587587
</td>
588588
</tr>
589+
<tr>
590+
<td>
591+
defaultSqlProviderType
592+
</td>
593+
<td>
594+
SQLを提供するメソッドを保持するSQLプロバイダクラスを指定します(導入されたバージョン: 3.5.6)。
595+
ここで指定したクラスは、SQLプロバイダアノテーション(例: <code>@SelectProvider</code>)の<code>type</code>(または <code>value</code>) 属性を省略した際に適用されます。
596+
</td>
597+
<td>
598+
タイプエイリアスまたは完全修飾クラス名
599+
</td>
600+
<td>
601+
未指定
602+
</td>
603+
</tr>
589604
</tbody>
590605
</table>
591606
<p>

src/site/ja/xdoc/java-api.xml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,8 @@ void rollback(boolean force)</source>
491491
なお、メソッド引数にはMapperメソッドの引数に渡したオブジェクトに加え、<code>ProviderContext</code>(MyBatis 3.4.5以降で利用可能)を介して「Mapperインタフェースの型」「Mapperメソッド」「データベースID」を渡すことができます。(MyBatis 3.4以降では、複数の引数を渡すことができます)
492492
キー: <code>value</code>, <code>type</code>, <code>method</code>.
493493
<code>value</code> と <code>type</code> にはクラスオブジェクトを指定します
494-
(<code>type</code> は <code>value</code> の別名で、どちらか一方を指定する必要があります)。
494+
(<code>type</code> は <code>value</code> の別名で、どちらか一方を指定する必要があります。
495+
ただし、グローバル設定として<code>defaultSqlProviderType</code>を指定している場合は両方とも省略することができます)。
495496
<code>method</code> にはメソッド名を指定します
496497
(MyBatis 3.5.1以降では、<code>method</code> 属性を省略することができます。その際MyBatisは、<code>ProviderMethodResolver</code> インタフェースを介して対象メソッドの解決を試み、
497498
対象メソッドが解決できない場合は、<code>provideSql</code>という名前のメソッドを代替メソッドとして利用します)。
@@ -619,6 +620,29 @@ class UserSqlBuilder {
619620
}
620621
}]]></source>
621622

623+
<p>次のコードは、グローバル設定を利用して全てのマッパーメソッドで同じSQLプロバイダクラスを利用する例です。(3.5.6以降で利用可能)</p>
624+
<source><![CDATA[
625+
Configuration configuration = new Configuration();
626+
configuration.setDefaultSqlProviderType(TemplateFilePathProvider.class); // 全てのマッパーメソッドで利用するSQLプロバイダクラスを指定する
627+
// ...]]></source>
628+
<source><![CDATA[
629+
// 各メソッドのSQLプロバイダアノテーションの type または value 属性は省略することができ、
630+
// 省略した場合はMyBaitsはグローバル設定の defaultSqlProviderType に指定されているクラスを適用する
631+
public interface UserMapper {
632+
633+
@SelectProvider // @SelectProvider(TemplateFilePathProvider.class) と同義
634+
User findUser(int id);
635+
636+
@InsertProvider // @InsertProvider(TemplateFilePathProvider.class) と同義
637+
void createUser(User user);
638+
639+
@UpdateProvider // @UpdateProvider(TemplateFilePathProvider.class) と同義
640+
void updateUser(User user);
641+
642+
@DeleteProvider // @DeleteProvider(TemplateFilePathProvider.class) と同義
643+
void deleteUser(int id);
644+
}]]></source>
645+
622646
<p>次のコードは、<code>ProviderMethodResolver</code>(MyBatis 3.5.1以降で利用可能)のデフォルト実装の利用例です。</p>
623647
<source><![CDATA[@SelectProvider(UserSqlProvider.class)
624648
List<User> getUsersByName(String name);

src/site/ko/xdoc/configuration.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,22 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environ
569569
false
570570
</td>
571571
</tr>
572+
<tr>
573+
<td>
574+
defaultSqlProviderType
575+
</td>
576+
<td>
577+
Specifies an sql provider class that holds provider method (Since 3.5.6).
578+
This class apply to the <code>type</code>(or <code>value</code>) attribute on sql provider annotation(e.g. <code>@SelectProvider</code>),
579+
when these attribute was omitted.
580+
</td>
581+
<td>
582+
A type alias or fully qualified class name
583+
</td>
584+
<td>
585+
Not set
586+
</td>
587+
</tr>
572588
</tbody>
573589
</table>
574590
<p>위 설정을 모두 사용한 setting 엘리먼트의 예제이다:</p>

src/site/ko/xdoc/java-api.xml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,8 @@ void rollback(boolean force)</source>
605605
매핑된 구문을 실행할 때 마이바티스는 클래스의 인스턴스를 만들고 메소드를 실행한다.
606606
Mapper 메서드의 인수인 "Mapper interface type" and "Database ID" 과 <code>ProviderContext</code>(Mybatis 3.4.5 부터) 를 이용한 "Mapper method" 로 전달 된 객체를 메서드 매개변수로 전달할 수 있다.(마이바티스 3.4이상에서는 복수 파라미터를 허용한다.)
607607
사용가능한 속성들 : value, type, method.
608-
value and type 속성은 클래스 (The <code>type</code> attribute is alias for <code>value</code>, you must be specify either one).
608+
value and type 속성은 클래스 (The <code>type</code> attribute is alias for <code>value</code>, you must be specify either one.
609+
But both attributes can be omit when specify the <code>defaultSqlProviderType</code> as global configuration).
609610
method 속성은 메소드명이다
610611
(Since 3.5.1, you can omit <code>method</code> attribute, the MyBatis will resolve a target method via the
611612
<code>ProviderMethodResolver</code> interface.
@@ -749,6 +750,29 @@ class UserSqlBuilder {
749750
}
750751
}]]></source>
751752

753+
<p>This example shows usage that share an sql provider class to all mapper methods using global configuration(Available since 3.5.6):</p>
754+
<source><![CDATA[
755+
Configuration configuration = new Configuration();
756+
configuration.setDefaultSqlProviderType(TemplateFilePathProvider.class); // Specify an sql provider class for sharing on all mapper methods
757+
// ...]]></source>
758+
<source><![CDATA[
759+
// Can omit the type/value attribute on sql provider annotation
760+
// If omit it, the MyBatis apply the class that specified on defaultSqlProviderType.
761+
public interface UserMapper {
762+
763+
@SelectProvider // Same with @SelectProvider(TemplateFilePathProvider.class)
764+
User findUser(int id);
765+
766+
@InsertProvider // Same with @InsertProvider(TemplateFilePathProvider.class)
767+
void createUser(User user);
768+
769+
@UpdateProvider // Same with @UpdateProvider(TemplateFilePathProvider.class)
770+
void updateUser(User user);
771+
772+
@DeleteProvider // Same with @DeleteProvider(TemplateFilePathProvider.class)
773+
void deleteUser(int id);
774+
}]]></source>
775+
752776
<p>This example shows usage the default implementation of <code>ProviderMethodResolver</code>(available since MyBatis 3.5.1 or later):</p>
753777
<source><![CDATA[@SelectProvider(UserSqlProvider.class)
754778
List<User> getUsersByName(String name);

src/site/xdoc/configuration.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,22 @@ SqlSessionFactory factory =
648648
false
649649
</td>
650650
</tr>
651+
<tr>
652+
<td>
653+
defaultSqlProviderType
654+
</td>
655+
<td>
656+
Specifies an sql provider class that holds provider method (Since 3.5.6).
657+
This class apply to the <code>type</code>(or <code>value</code>) attribute on sql provider annotation(e.g. <code>@SelectProvider</code>),
658+
when these attribute was omitted.
659+
</td>
660+
<td>
661+
A type alias or fully qualified class name
662+
</td>
663+
<td>
664+
Not set
665+
</td>
666+
</tr>
651667
</tbody>
652668
</table>
653669
<p>

0 commit comments

Comments
 (0)