diff --git a/src/main/java/org/apache/ibatis/builder/annotation/ProviderContext.java b/src/main/java/org/apache/ibatis/builder/annotation/ProviderContext.java index 38f0d46d427..0377719349f 100644 --- a/src/main/java/org/apache/ibatis/builder/annotation/ProviderContext.java +++ b/src/main/java/org/apache/ibatis/builder/annotation/ProviderContext.java @@ -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. @@ -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; } /** @@ -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; + } + } diff --git a/src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java b/src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java index cc047832d05..eb8bf9ae48e 100644 --- a/src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java +++ b/src/main/java/org/apache/ibatis/builder/annotation/ProviderSqlSource.java @@ -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; @@ -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; } } diff --git a/src/site/es/xdoc/java-api.xml b/src/site/es/xdoc/java-api.xml index 331399f3d25..e5e797421e4 100644 --- a/src/site/es/xdoc/java-api.xml +++ b/src/site/es/xdoc/java-api.xml @@ -463,7 +463,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) { 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 CharSequence instead of String 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 ProviderContext(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 diff --git a/src/site/ja/xdoc/java-api.xml b/src/site/ja/xdoc/java-api.xml index 52a4b89e4e5..9ad2aa3a777 100644 --- a/src/site/ja/xdoc/java-api.xml +++ b/src/site/ja/xdoc/java-api.xml @@ -476,7 +476,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) { これらのアノテーションは動的 SQL を生成するためのものです。実行時に指定されたメソッドが呼び出され、メソッドから返された SQL ステートメントが実行されます (MyBatis 3.4.6以降では、メソッドの返り値として String ではなく CharSequence を指定することができます)。 マップドステートメントを実行する際、プロバイダーによって指定したクラスのインスタンスが作成され、指定されたメソッドが実行されます。 - なお、メソッド引数にはMapperメソッドの引数に渡したオブジェクトに加え、ProviderContext(MyBatis 3.4.5以降で利用可能)を介して「Mapperインタフェースの型」と「Mapperメソッド」を渡すことができます。(MyBatis 3.4以降では、複数の引数を渡すことができます) + なお、メソッド引数にはMapperメソッドの引数に渡したオブジェクトに加え、ProviderContext(MyBatis 3.4.5以降で利用可能)を介して「Mapperインタフェースの型」「Mapperメソッド」「データベースID」を渡すことができます。(MyBatis 3.4以降では、複数の引数を渡すことができます) キー: type, method. type にはクラスオブジェクト、method にはメソッド名を指定します (MyBatis 3.5.1以降では、method 属性を省略することができます。その際MyBatisは、ProviderMethodResolver インタフェースを介して対象メソッドの解決を試み、 対象メソッドが解決できない場合は、provideSqlという名前のメソッドを代替メソッドとして利用します)。 diff --git a/src/site/ko/xdoc/java-api.xml b/src/site/ko/xdoc/java-api.xml index dd5aad87e0d..a175609266b 100644 --- a/src/site/ko/xdoc/java-api.xml +++ b/src/site/ko/xdoc/java-api.xml @@ -598,7 +598,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) { 실행시 SQL 을 리턴할 클래스 과 메소드명을 명시하도록 해주는 대체수단의 애노테이션이다 (Since 3.4.6, you can specify the CharSequence instead of String as a method return type). 매핑된 구문을 실행할 때 마이바티스는 클래스의 인스턴스를 만들고 메소드를 실행한다. - Mapper 메서드의 인수인 "Mapper interface type" 과 ProviderContext(Mybatis 3.4.5 부터) 를 이용한 "Mapper method" 로 전달 된 객체를 메서드 매개변수로 전달할 수 있다.(마이바티스 3.4이상에서는 복수 파라미터를 허용한다.) + Mapper 메서드의 인수인 "Mapper interface type" and "Database ID" 과 ProviderContext(Mybatis 3.4.5 부터) 를 이용한 "Mapper method" 로 전달 된 객체를 메서드 매개변수로 전달할 수 있다.(마이바티스 3.4이상에서는 복수 파라미터를 허용한다.) 사용가능한 속성들 : type, method. type 속성은 클래스. method 속성은 메소드명이다 diff --git a/src/site/xdoc/java-api.xml b/src/site/xdoc/java-api.xml index 55f9ecb04e8..47cdd24113b 100644 --- a/src/site/xdoc/java-api.xml +++ b/src/site/xdoc/java-api.xml @@ -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 CharSequence instead of String 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 ProviderContext(available since MyBatis 3.4.5 or later) as method argument. (In MyBatis 3.4 or later, it's allow multiple parameters) Attributes: type, method. The type attribute is a class. diff --git a/src/site/zh/xdoc/java-api.xml b/src/site/zh/xdoc/java-api.xml index d36515c1f3b..b57af3a2c5b 100644 --- a/src/site/zh/xdoc/java-api.xml +++ b/src/site/zh/xdoc/java-api.xml @@ -465,7 +465,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
  • <select>
  • -        允许构建动态 SQL。这些备选的 SQL 注解允许你指定类名和返回在运行时执行的 SQL 语句的方法。(自从MyBatis 3.4.6开始,你可以用 CharSequence 代替 String 来返回类型返回值了。)当执行映射语句的时候,MyBatis 会实例化类并执行方法,类和方法就是填入了注解的值。你可以把已经传递给映射方法了的对象作为参数,"Mapper interface type" 和 "Mapper method" 会经过 ProviderContext (仅在MyBatis 3.4.5及以上支持)作为参数值。(MyBatis 3.4及以上的版本,支持多参数传入) +        允许构建动态 SQL。这些备选的 SQL 注解允许你指定类名和返回在运行时执行的 SQL 语句的方法。(自从MyBatis 3.4.6开始,你可以用 CharSequence 代替 String 来返回类型返回值了。)当执行映射语句的时候,MyBatis 会实例化类并执行方法,类和方法就是填入了注解的值。你可以把已经传递给映射方法了的对象作为参数,"Mapper interface type" 和 "Mapper method" and "Database ID" 会经过 ProviderContext (仅在MyBatis 3.4.5及以上支持)作为参数值。(MyBatis 3.4及以上的版本,支持多参数传入) 属性有: type, methodtype 属性需填入类。 method 需填入该类定义了的方法名 diff --git a/src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java b/src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java index 1a526bab77f..60f8339858c 100644 --- a/src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java +++ b/src/test/java/org/apache/ibatis/submitted/sqlprovider/SqlProviderTest.java @@ -45,6 +45,7 @@ class SqlProviderTest { private static SqlSessionFactory sqlSessionFactory; + private static SqlSessionFactory sqlSessionFactoryForDerby; @BeforeAll static void setUp() throws Exception { @@ -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 @@ -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"; + } + } + } + } + } diff --git a/src/test/java/org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml b/src/test/java/org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml index 99a665aa7d8..f89cfaba1da 100644 --- a/src/test/java/org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml +++ b/src/test/java/org/apache/ibatis/submitted/sqlprovider/mybatis-config.xml @@ -1,7 +1,7 @@