2016-11-10 65 views
1

我有一個要求,即在將數據返回給用戶之前連接到多個數據庫以查詢和合並數據。有沒有使用MyBatis和cdi的方法?我看着使用DatabaseIdProvidermultiple environment configurations,但看起來他們不會在這種情況下工作。通過多種環境配置,我可以創建不同的sql會話工廠,但映射器的cdi在這種情況下如何工作?我想盡可能地使用cdi。 MyBatis Guice會幫忙嗎?我看了一個similar的問題,但我無法確定Guice是否會在這種情況下幫助我需要在同一個服務調用中查詢多個數據庫。MyBatis - 在同一服務調用中連接到多個數據庫

回答

0

環境配置定義數據源和事務管理器。 然後連接到多個數據庫至少需要儘可能多的的SqlSessionFactory

Reader reader = Resources.getResourceAsReader(classpathConfigFilename); 
new SqlSessionFactoryBuilder().build(reader, environment, properties); 

電話爲每個環境

如果目的是鞏固的數據,我想這兩個數據模型略有不同(那麼查詢,映射器,typeHandler ...),那麼SqlSessionFactory最好從不同的mybatis-config文件創建並使用它們的默認環境:

new SqlSessionFactoryBuilder().build(reader, properties); 

這是怎麼解決不了的問題? 如果您編輯問題以提供有關上下文,示例以及您嘗試的更多信息,則可能會帶來更準確的答案。

Guice:當然可以使用,但不是此成就所必需的。

編輯:

使用Mybatis-CDI

這裏是如何產生的SqlSession工廠(他們必須@Named):

import javax.enterprise.context.ApplicationScoped; 
import javax.enterprise.inject.Produces; 
import javax.inject.Named; 

public class SqlSessionFactoryWrapper { 

    private static final String BI_CONFIG = "mybatis-config.xml"; 

    private SqlSessionFactory getFactory(final String config, final String env) throws IOException { 
     final Reader reader = Resources.getResourceAsReader(config); 
     final Properties properties = new Properties(); 
     properties.load(Resources.getResourceAsReader("some.properties")); 

     return new SqlSessionFactoryBuilder().build(reader, env, properties); 
    } 

    @Produces 
    @ApplicationScoped 
    @Named("A") 
    public SqlSessionFactory getFactoryA() throws IOException { 
     return this.getBiFactory(CONFIG, "A"); 
    } 

    @Produces 
    @ApplicationScoped 
    @Named("B") 
    public SqlSessionFactory getFactoryB() throws IOException { 
     return this.getFactory(CONFIG, "B"); 
    } 
} 

而如何注入:

import javax.enterprise.context.ApplicationScoped; 
import javax.inject.Inject; 
import javax.inject.Named; 


    @Inject 
    @Named("A") 
    protected SqlSession   sessionA; 

    @Inject 
    @Named("B") 
    protected SqlSession   sessionB; 

注入從環境的SqlSession直接映射

import org.mybatis.cdi.Mapper; 

    @Inject 
    @Named("B") 
    @Mapper 
    protected MyMapper mapper; 

這在JBoss上運行我的應用程序的工作,但並沒有什麼具體的JBoss的位置。

閱讀documentation for transaction management,這很清楚。 我建議使用

@Transactional(executorType = ExecutorType.REUSE) 

specialy批量操作一次準備的語句。

EDIT2:在片段

mybatis.cdi標註的有效期爲我所用,然後版本1.0.0.beta3。在進一步的測試中,他們已經有了一些進化,然後很少有適應能力與最終版本一起工作(僅用了一個月)。

+0

感謝您的回答。我更新了這個問題。 – Ulysses

+0

根據您的問題更新編輯答案 – blackwizard

1

您將需要定義2個SqlSessionFactories。單獨的環境可能適合您的需求,但也可以使用完全獨立的配置和對象/類層次結構。無論如何,您可以根據需要在映射器或映射器掃描器的配置中傳遞每一個。

請參閱documentation瞭解配置映射器的各種方法。請注意,如果需要,它們都允許您指定SqlSessionFactory。如果每個配置使用相同的映射器,則可能無法使用掃描器方法,因爲我認爲這將對來自不同SqlSessionFactory的映射器使用相同的名稱。在這種情況下,您將不得不爲不同的配置使用不同的名稱來手動配置映射器。

然後在你的服務,你可以這樣做:

public class FooServiceImpl implements FooService { 
    @Autowired 
    @Qualifier("fooMapperDB1") 
    private FooMapper fooMapper1; 

    @Autowired 
    @Qualifier("fooMapperDB2") 
    private FooMapper fooMapper2; 

    public List<Foo> doService(String id) { 
    List<Foo> toReturn = new ArrayList<>(); 
    toReturn.add(fooMapper1.getFoo()); 
    toReturn.add(fooMapper2.getFoo()); 
    return toReturn; 
    } 
} 

請注意,您要小心這裏的交易。您可能希望該服務是事務性的,然後爲兩個數據庫連接使用分佈式XA數據源。

相關問題