2016-11-10 29 views
1

私は、複数のデータベースに接続してデータを照会して統合し、ユーザーに返す必要があります。 MyBatisとcdiを使ってそれを行う方法はありますか?私はDatabaseIdProviderを使用し、multiple environment configurationsを持っていましたが、このシナリオではうまくいかないようです。複数の環境設定では、異なるSQLセッションファクトリを作成できますが、その場合マッパーのためのcdiはどのように機能しますか?私は可能な限りcdiを使用したいと思います。 MyBatis Guiceはこれを手伝いますか?私はsimilar質問を見ましたが、同じサービスコールで複数のデータベースを照会する必要がある場合、Guiceがこの場合に役立つかどうか判断できません。MyBatis - 同じサービスコールで複数のデータベースに接続する

答えて

0

環境設定では、データソースとトランザクションマネージャが定義されています。そして、複数のデータベースへの接続 は、少なくとも同じくらいSqlSessionFactory必要があります。各環境

ため

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

コール1を目的のデータを統合することであるならば、私は(両方のデータモデルは、わずかに異なっていると思いますクエリ、マッパー、typeHandlerなど)、SqlSessionFactoryはさまざまなmybatis-configファイルから作成し、デフォルト環境を使用することをお勧めします。

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

どのように問題を解決できないのですか? 質問を編集して、コンテキスト、例、試したことについての詳細な情報を提供すれば、より正確な回答が得られるかもしれません。

Guice:勿論使用することができますが、この達成には必要ありません。

EDIT:

使用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; 

またはは、環境BSQLSESSIONからのため直接マッパー注入:

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有効です。さらに進んだベータ版ではわずかに進化しており、最終リリース(わずか1ヶ月間)で作業するために必要な適応はほとんどありません。

+0

あなたの答えをありがとう。私は質問を更新しました。 – Ulysses

+0

あなたの質問に従って編集された回答update – blackwizard

1

2つのSqlSessionFactoriesが定義されている必要があります。個別の環境がニーズに合っているかもしれませんが、完全に別々の設定とオブジェクト/クラス階層を使用することも可能です。それにかかわらず、マッパーやマッパースキャナーの設定では、必要に応じてそれぞれを渡すことができます。

マッパーを構成するさまざまな方法については、documentationを参照してください。必要に応じて、それらのすべてでSqlSessionFactoryを指定できることに注意してください。それぞれの設定が同じマッパーを使用している場合は、異なるSqlSessionFactoriesのマッパーに同じ名前を使用すると思われるので、スキャナーのアプローチを使用できない場合があります。その場合は、異なるコンフィグレーションに異なる名前を使用してマッパーを手動で設定する必要があります。あなたが取引して、ここで注意する必要があります

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; 
    } 
} 

注:

次に、あなたのサービスであなたのような何かを行うことができます。おそらく、サービスをトランザクションにしてから、両方のDB接続に分散XAデータソースを使用することをお勧めします。

関連する問題