2013-08-13 16 views
13

İlkbahar ve Mybatis ile çalışıyorum ve iki veritabanım var, ilk veritabanının yapılandırması göreceli olarak kolaydı, ancak ikinci veritabanını Spring ve işlemlerle çalıştıramadım. benim kodMybatis Spring çoklu veritabanları Java yapılandırması

@Configuration 
@ComponentScan(basePackages = {"hernandez.service", "hernandez.dao"}) 
@EnableTransactionManagement 
@MapperScan(basePackages="hernandez.mapper") 
@Import(DbConfig2.class) 
public class AppConfig { 

@Bean(name = "dataSource") 
public DataSource dataSource() { 
    DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver", 
      "jdbc:mysql://localhost:3306/northwind", "root", ""); 
    return ds; 
} 

@Bean 
public SqlSessionFactoryBean sqlSessionFactory() { 
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); 
    factoryBean.setDataSource(dataSource()); 
    return factoryBean; 
} 

@Bean(name = "transactionManager") 
public PlatformTransactionManager transactionManager() { 
    return new DataSourceTransactionManager(dataSource()); 
} 
} 

@Configuration 
@MapperScan("loli.mapper") 
public class DbConfig2 { 
@Bean(name = "dataSource_2") 
public DataSource dataSource2() { 
    DriverManagerDataSource ds = new DriverManagerDataSource("com.mysql.jdbc.Driver", 
      "jdbc:mysql://localhost:3306/dmsolut_dmsms", "root", ""); 
    return ds; 
} 

@Bean 
public SqlSessionFactory sqlSessionFactory2() throws Exception{ 
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); 
    factoryBean.setDataSource(dataSource2()); 
    return factoryBean.getObject(); 
} 

@Bean(name = "transactionManager_2") 
public PlatformTransactionManager transactionManager() { 
    return new DataSourceTransactionManager(dataSource2()); 
} 
} 

saf Bahar Java yapılandırma ile ya da en azından bazı XML ile çalışma Bu almanın bir yolu var mı nedir? Mybatis-Spring projesinde

cevap

17

'da iki veritabanının çalışmasını sağlamak için resmi bir belge bulunmamaktadır. Mybatis ile çoklu veri kaynakları şu anda projemde kullanılmaktadır. Bu örnek olduğunu da application.xml için projemize kullandığımız java yapılandırma örnekle

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> 
    <property name="url" value="${center.connectionURL}"/> 
    <property name="username" value="${userName}"/> 
    <property name="password" value="${password}"/> 
</bean> 

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
    <property name="basePackage" value="com.xxx.dao.center"/> 
    <property name="sqlSessionFactoryBeanName" value="cneterSqlSessionFactory"/> 
</bean> 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" name="cneterSqlSessionFactory"> 
    <property name="dataSource" ref="dataSource"></property> 
    <property name="mapperLocations" value="classpath*:mapperConfig/center/*.xml"/> 
    <property name="configLocation" value="classpath:mybatis-config.xml"/> 
</bean> 

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 
<tx:annotation-driven transaction-manager="transactionManager"/> 
<!--center db end--> 
<!--exdb--> 
<bean id="dataSourceEx" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> 
    <property name="url" value="${ex.connectionURL}"/> 
    <property name="username" value="${userName}"/> 
    <property name="password" value="${password}"/> 
</bean> 
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
    <property name="basePackage" value="com.xxx.dao.ex"/> 
    <property name="sqlSessionFactoryBeanName" value="exSqlSessionFactory"/> 
</bean> 
<bean id="sqlSessionFactoryEx" class="org.mybatis.spring.SqlSessionFactoryBean" name="exSqlSessionFactory"> 
    <property name="dataSource" ref="dataSourceEx"></property> 
    <property name="mapperLocations" value="classpath*:mapperConfig/ex/*.xml"/> 
    <property name="configLocation" value="classpath:mybatis-config.xml"/> 
</bean> 
<bean id="transactionManagerEx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSourceEx"/> 
</bean> 
+7

Java Yapılandırması'nı kullanarak bunu yapmanın bir yolu var mı? –

+0

Henüz denemedim. Sadece mybatis'i XML ile bahar ile kullanıyorum. –

10

Ekleme cevap ekleyin: Tecrübelerime göre

import org.apache.ibatis.session.SqlSessionFactory; 
import org.apache.ibatis.type.JdbcType; 
import org.mybatis.spring.SqlSessionFactoryBean; 
import org.mybatis.spring.mapper.MapperScannerConfigurer; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.jdbc.datasource.DataSourceTransactionManager; 
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; 
import org.springframework.transaction.PlatformTransactionManager; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 

import javax.sql.DataSource; 

@Configuration 
@ComponentScan(basePackages = "com.mycompany") 
@EnableTransactionManagement(proxyTargetClass = true) 
public class ApplicationConfig2 { 
    public static final String DATA_SOURCE_NAME_1 = "jdbc/dataSource1"; 
    public static final String DATA_SOURCE_NAME_2 = "jdbc/dataSource2"; 

    public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1"; 
    public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2"; 

    public static final String MAPPERS_PACKAGE_NAME_1 = "com.mycompany.mappers.dao1"; 
    public static final String MAPPERS_PACKAGE_NAME_2 = "com.mycompany.mappers.dao2"; 

    @Bean 
    public DataSource dataSource1() { 
     JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
     return dsLookup.getDataSource(DATA_SOURCE_NAME_1); 
    } 

    @Bean 
    public DataSource dataSource2() { 
     JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
     return dsLookup.getDataSource(DATA_SOURCE_NAME_2); 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager() { 
     return new DataSourceTransactionManager(dataSource()); 
    } 


    @Bean(name = SQL_SESSION_FACTORY_NAME_1) 
    public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1) throws Exception { 
     SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 
     sqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); 
     sqlSessionFactoryBean.setDataSource(dataSource1); 
     SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject(); 
     sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); 
     sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); 
     return sqlSessionFactory; 
    } 

    @Bean(name = SQL_SESSION_FACTORY_NAME_2) 
    public SqlSessionFactory sqlSessionFactory2(DataSource dataSource2) throws Exception { 
     SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean(); 
     diSqlSessionFactoryBean.setTypeHandlersPackage(DateTimeTypeHandler.class.getPackage().getName()); 
     diSqlSessionFactoryBean.setDataSource(dataSource2); 
     SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject(); 
     sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); 
     sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); 
     return sqlSessionFactory; 
    } 

    @Bean 
    public MapperScannerConfigurer mapperScannerConfigurer1() { 
     MapperScannerConfigurer configurer = new MapperScannerConfigurer(); 
     configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1); 
     configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1); 
     return configurer; 
    } 

    @Bean 
    public MapperScannerConfigurer mapperScannerConfigurer2() { 
     MapperScannerConfigurer configurer = new MapperScannerConfigurer(); 
     configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2); 
     configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2); 
     return configurer; 
    } 
} 
+1

transactionManager'a ne dersiniz? Hangi dataSource kullanmalı? –

+0

Bazen veri kaynağı, transactionManager ve SqlSessionFactory'yi birincil olarak atamanız gerekebilir. –

2

, ayrıca birine @Primary eklemek gerekir DataSource fasulye. Aksi halde NoUniqueBeanDefinitionException'u atar.

@Bean 
@Primary 
public DataSource dataSource1() { 
    JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
    return dsLookup.getDataSource(DATA_SOURCE_NAME_1); 
} 

@Bean 
public DataSource dataSource2() { 
    JndiDataSourceLookup dsLookup = new JndiDataSourceLookup(); 
    return dsLookup.getDataSource(DATA_SOURCE_NAME_2); 
} 
1

Bunu uzanan ve yöntem determineCurrentLookupKey() geçersiz kılarak yay en AbstractRoutingDataSource kullanabilirsiniz.

Yay Yapılandırma

Eğer yay yapılandırma ayrı datasource tanımlayabilir.

<!-- db2 data source --> 
<bean id="db2DataSource" class="com.ibm.db2.jdbc.app.DB2Driver"> 
    <property name="serverName" value="${db2.jdbc.serverName}" /> 
    <property name="portNumber" value="${db2.jdbc.portNumber}" /> 
    <property name="user" value="${db2.jdbc.username}" /> 
    <property name="password" value="${db2.jdbc.password}" /> 
    <property name="databaseName" value="${db2.jdbc.databaseName}" /> 
</bean> 

<!-- mysql data source --> 
<bean id="mysqlDataSource" class="com.mysql.jdbc.Driver"> 
    <property name="serverName" value="${mysql.jdbc.serverName}" /> 
    <property name="portNumber" value="${mysql.jdbc.portNumber}" /> 
    <property name="user" value="${mysql.jdbc.username}" /> 
    <property name="password" value="${mysql.jdbc.password}" /> 
    <property name="databaseName" value="${mysql.jdbc.databaseName}" /> 
</bean> 

Ön müşteri ile veri kaynağı:

Java Temelde

package com.example; 

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 

public class CustomerRoutingDataSource extends AbstractRoutingDataSource { 

@Bean 
CustomerContextHolder context; 

@Override 
protected Object determineCurrentLookupKey() { 
    return context.getCustomerType(); 
} 
} 

, her istek Bağlamını sahip olacaktır. Eşleştirilen anahtarı kullanarak istek ile datasource ilişkilendirebilirsiniz. Yukarıda belirtildiği gibi, biz sizin DaoImpl içinde sessionFactory tekabül vermek gerekir burada dynamic-datasource-routing

0

<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource1" /> 
    <property name="configLocation"> 
     <value>classpath:com/dtcc/dao/impl/DaoSqlMapConfig_MyBatis1.xml</value> 
    </property> 
    <property name="transactionFactory"> 
     <bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" /> 
    </property> 
    <property name="mapperLocations" value="classpath*:com/dtcc/dao/impl/DaoEmfMyBatis.sp.xml"/> 
</bean> 
<bean id="sqlSession1" class="org.mybatis.spring.SqlSessionTemplate"> 
    <constructor-arg index="0" ref="sqlSessionFactory1" /> 
</bean> 
<!-- MyBatis Changes Ends --> 

<bean id="daoEmf" class="com.dtcc.dao.DaoEmfImpl"> 
    <property name="connectionType"><ref local="com.dtcc.sharedservices.utils.resources.ConnTypes.IBM_DB2_CONNECTION" /></property> 
    <property name="jndiNameForLogging"><ref local="dataSourceName1" /></property> 
    <property name="sqlSessionTemplate"> <ref local="sqlSession1" /></property> 
    <property name="applicationLog"><ref local="appLog" /></property> 
</bean> 

fazla ayrıntı bulabilirsiniz. Birden fazla sessionFactory varsa, DaoImpl sınıfınızda SqlSessionTemplate'ı otomatikleştiremezsiniz. Her oturum fabrikası için benzersiz bir isim verin ve ilgili DaoImpl sınıfınıza eşleyin. Tüm yapmanız gereken DaoImpl sınıfında Setter yöntemiyle SqlSessionTemplate için nesne oluşturmak ve db aramasını aşağıdaki gibi sqlSessionTemplate nesnesini kullanarak yapabilirsiniz, this.sqlSessionTemplate.selectList ("ProcedureID", parameter));

İlgili konular