Skip to content

Support databaseId at ProviderContext #1503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2009-2017 the original author or authors.
* Copyright 2009-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.
Expand Down Expand Up @@ -27,16 +27,19 @@ public final class ProviderContext {

private final Class<?> mapperType;
private final Method mapperMethod;
private final String databaseId;

/**
* Constructor.
*
* @param mapperType A mapper interface type that specified provider
* @param mapperMethod A mapper method that specified provider
* @param databaseId A database id
*/
ProviderContext(Class<?> mapperType, Method mapperMethod) {
ProviderContext(Class<?> mapperType, Method mapperMethod, String databaseId) {
this.mapperType = mapperType;
this.mapperMethod = mapperMethod;
this.databaseId = databaseId;
}

/**
Expand All @@ -57,4 +60,14 @@ public Method getMapperMethod() {
return mapperMethod;
}

/**
* Get a database id that provided from {@link org.apache.ibatis.mapping.DatabaseIdProvider}.
*
* @return A database id
* @since 3.5.1
*/
public String getDatabaseId() {
return databaseId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public ProviderSqlSource(Configuration configuration, Object provider, Class<?>

if (providerMethodName.length() == 0 && ProviderMethodResolver.class.isAssignableFrom(this.providerType)) {
this.providerMethod = ((ProviderMethodResolver) this.providerType.getDeclaredConstructor().newInstance())
.resolveMethod(new ProviderContext(mapperType, mapperMethod));
.resolveMethod(new ProviderContext(mapperType, mapperMethod, configuration.getDatabaseId()));
}
if (this.providerMethod == null) {
providerMethodName = providerMethodName.length() == 0 ? "provideSql" : providerMethodName;
Expand Down Expand Up @@ -98,7 +98,7 @@ public ProviderSqlSource(Configuration configuration, Object provider, Class<?>
+ this.providerType.getName() + "." + providerMethod.getName()
+ "). ProviderContext can not define multiple in SqlProvider method argument.");
}
this.providerContext = new ProviderContext(mapperType, mapperMethod);
this.providerContext = new ProviderContext(mapperType, mapperMethod, configuration.getDatabaseId());
this.providerContextIndex = i;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/site/es/xdoc/java-api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
</ul>
</td>
<td>Estas anotaciones SQL alternativas te permiten especificar un nombre de clases y un método que devolverán la SQL que debe ejecutarse (Since 3.4.6, you can specify the <code>CharSequence</code> instead of <code>String</code> as a method return type).
Cuando se ejecute el método MyBatis instanciará la clase y ejecutará el método especificados en el provider. You can pass objects that passed to arguments of a mapper method, "Mapper interface type" and "Mapper method"
Cuando se ejecute el método MyBatis instanciará la clase y ejecutará el método especificados en el provider. You can pass objects that passed to arguments of a mapper method, "Mapper interface type", "Mapper method" and "Database ID"
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)
Atributos: type, method. El atributo type es el nombre completamente cualificado de una clase.
El method es el nombre un método de dicha clase
Expand Down
2 changes: 1 addition & 1 deletion src/site/ja/xdoc/java-api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
</td>
<td>これらのアノテーションは動的 SQL を生成するためのものです。実行時に指定されたメソッドが呼び出され、メソッドから返された SQL ステートメントが実行されます (MyBatis 3.4.6以降では、メソッドの返り値として <code>String</code> ではなく <code>CharSequence</code> を指定することができます)。
マップドステートメントを実行する際、プロバイダーによって指定したクラスのインスタンスが作成され、指定されたメソッドが実行されます。
なお、メソッド引数にはMapperメソッドの引数に渡したオブジェクトに加え、<code>ProviderContext</code>(MyBatis 3.4.5以降で利用可能)を介して「Mapperインタフェースの型」「Mapperメソッド」を渡すことができます。(MyBatis 3.4以降では、複数の引数を渡すことができます)
なお、メソッド引数にはMapperメソッドの引数に渡したオブジェクトに加え、<code>ProviderContext</code>(MyBatis 3.4.5以降で利用可能)を介して「Mapperインタフェースの型」「Mapperメソッド」「データベースID」を渡すことができます。(MyBatis 3.4以降では、複数の引数を渡すことができます)
キー: <code>type</code>, <code>method</code>. <code>type</code> にはクラスオブジェクト、<code>method</code> にはメソッド名を指定します
(MyBatis 3.5.1以降では、<code>method</code> 属性を省略することができます。その際MyBatisは、<code>ProviderMethodResolver</code> インタフェースを介して対象メソッドの解決を試み、
対象メソッドが解決できない場合は、<code>provideSql</code>という名前のメソッドを代替メソッドとして利用します)。
Expand Down
2 changes: 1 addition & 1 deletion src/site/ko/xdoc/java-api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
</td>
<td>실행시 SQL 을 리턴할 클래스 과 메소드명을 명시하도록 해주는 대체수단의 애노테이션이다 (Since 3.4.6, you can specify the <code>CharSequence</code> instead of <code>String</code> as a method return type).
매핑된 구문을 실행할 때 마이바티스는 클래스의 인스턴스를 만들고 메소드를 실행한다.
Mapper 메서드의 인수인 "Mapper interface type" 과 <code>ProviderContext</code>(Mybatis 3.4.5 부터) 를 이용한 "Mapper method" 로 전달 된 객체를 메서드 매개변수로 전달할 수 있다.(마이바티스 3.4이상에서는 복수 파라미터를 허용한다.)
Mapper 메서드의 인수인 "Mapper interface type" and "Database ID" 과 <code>ProviderContext</code>(Mybatis 3.4.5 부터) 를 이용한 "Mapper method" 로 전달 된 객체를 메서드 매개변수로 전달할 수 있다.(마이바티스 3.4이상에서는 복수 파라미터를 허용한다.)
사용가능한 속성들 : type, method.
type 속성은 클래스.
method 속성은 메소드명이다
Expand Down
2 changes: 1 addition & 1 deletion src/site/xdoc/java-api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
a method name that will return the SQL to run at execution time
(Since 3.4.6, you can specify the <code>CharSequence</code> instead of <code>String</code> as a method return type).
Upon executing the mapped statement, MyBatis will instantiate the class, and execute the method, as specified by the provider.
You can pass objects that passed to arguments of a mapper method, "Mapper interface type" and "Mapper method"
You can pass objects that passed to arguments of a mapper method, "Mapper interface type", "Mapper method" and "Database ID"
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)
Attributes: <code>type</code>, <code>method</code>. The <code>type</code> attribute is a class.
Expand Down
2 changes: 1 addition & 1 deletion src/site/zh/xdoc/java-api.xml
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
<li><code>&lt;select&gt;</code></li>
</ul>
</td>
       <td>允许构建动态 SQL。这些备选的 SQL 注解允许你指定类名和返回在运行时执行的 SQL 语句的方法。(自从MyBatis 3.4.6开始,你可以用 <code>CharSequence</code> 代替 <code>String</code> 来返回类型返回值了。)当执行映射语句的时候,MyBatis 会实例化类并执行方法,类和方法就是填入了注解的值。你可以把已经传递给映射方法了的对象作为参数,"Mapper interface type" 和 "Mapper method" 会经过 <code>ProviderContext</code> (仅在MyBatis 3.4.5及以上支持)作为参数值。(MyBatis 3.4及以上的版本,支持多参数传入)
       <td>允许构建动态 SQL。这些备选的 SQL 注解允许你指定类名和返回在运行时执行的 SQL 语句的方法。(自从MyBatis 3.4.6开始,你可以用 <code>CharSequence</code> 代替 <code>String</code> 来返回类型返回值了。)当执行映射语句的时候,MyBatis 会实例化类并执行方法,类和方法就是填入了注解的值。你可以把已经传递给映射方法了的对象作为参数,"Mapper interface type" 和 "Mapper method" and "Database ID" 会经过 <code>ProviderContext</code> (仅在MyBatis 3.4.5及以上支持)作为参数值。(MyBatis 3.4及以上的版本,支持多参数传入)
属性有: <code>type</code>, <code>method</code>。
<code>type</code> 属性需填入类。
<code>method</code> 需填入该类定义了的方法名
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
class SqlProviderTest {

private static SqlSessionFactory sqlSessionFactory;
private static SqlSessionFactory sqlSessionFactoryForDerby;

@BeforeAll
static void setUp() throws Exception {
Expand All @@ -53,11 +54,18 @@ static void setUp() throws Exception {
.getResourceAsReader("org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml")) {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
sqlSessionFactory.getConfiguration().addMapper(StaticMethodSqlProviderMapper.class);
sqlSessionFactory.getConfiguration().addMapper(DatabaseIdMapper.class);
}

// populate in-memory database
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
"org/apache/ibatis/submitted/sqlprovider/CreateDB.sql");

// create a SqlSessionFactory
try (Reader reader = Resources
.getResourceAsReader("org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml")) {
sqlSessionFactoryForDerby = new SqlSessionFactoryBuilder().build(reader, "development-derby");
sqlSessionFactoryForDerby.getConfiguration().addMapper(DatabaseIdMapper.class);
}
}

// Test for list
Expand Down Expand Up @@ -597,4 +605,31 @@ public void mapperGetByEntity() {
}
}

@Test
void shouldPassedDatabaseIdToProviderMethod() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
assertEquals("hsql", mapper.selectDatabaseId());
}
try (SqlSession sqlSession = sqlSessionFactoryForDerby.openSession()){
DatabaseIdMapper mapper = sqlSession.getMapper(DatabaseIdMapper.class);
assertEquals("derby", mapper.selectDatabaseId());
}
}

interface DatabaseIdMapper {
@SelectProvider(type = SqlProvider.class)
String selectDatabaseId();

class SqlProvider {
public static String provideSql(ProviderContext context) {
if ("hsql".equals(context.getDatabaseId())) {
return "SELECT '" + context.getDatabaseId() + "' FROM INFORMATION_SCHEMA.SYSTEM_USERS";
} else {
return "SELECT '" + context.getDatabaseId() + "' FROM SYSIBM.SYSDUMMY1";
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--

Copyright 2009-2017 the original author or authors.
Copyright 2009-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.
Expand Down Expand Up @@ -38,8 +38,21 @@
<property name="username" value="sa" />
</dataSource>
</environment>
<environment id="development-derby">
<transactionManager type="JDBC" />
<dataSource type="UNPOOLED">
<property name="driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:target/derby/sqlprovider;create=true" />
<property name="username" value="" />
</dataSource>
</environment>
</environments>

<databaseIdProvider type="DB_VENDOR">
<property name="HSQL Database Engine" value="hsql"/>
<property name="Apache Derby" value="derby"/>
</databaseIdProvider>

<mappers>
<mapper class="org.apache.ibatis.submitted.sqlprovider.Mapper" />
</mappers>
Expand Down