2013-08-13 31 views
13

Tôi đang làm việc với Spring và Mybatis và tôi có hai cơ sở dữ liệu, cấu hình cho cơ sở dữ liệu đầu tiên tương đối dễ dàng, nhưng tôi không thể làm việc với cơ sở dữ liệu thứ hai với Spring và các giao dịch. là mã của tôiMybatis Spring cấu hình cơ sở dữ liệu Java

@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()); 
} 
} 

Có cách nào để làm việc này với cấu hình Spring Java thuần túy hoặc ít nhất với một số XML không? Không có tài liệu chính thức nào để có hai cơ sở dữ liệu hoạt động trong dự án Mybatis-Spring

Trả lời

17

Nhiều nguồn dữ liệu với mybatis được sử dụng trong dự án của tôi ngay bây giờ. Đây là một ví dụ, thêm vào application.xml bạn

<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

Có cách nào để thực hiện việc này bằng cách sử dụng Cấu hình Java không? –

+0

Tôi chưa thử. Tôi chỉ sử dụng mybatis với spring bằng cấu hình XML. –

10

Thêm câu trả lời với ví dụ java cấu hình chúng tôi sử dụng trong dự án của chúng tôi:

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

Làm thế nào về transactionManager? dataSource nào nên sử dụng? –

+0

Đôi khi bạn có thể cần gán nguồn dữ liệu, transactionManager và SqlSessionFactory làm tất cả. –

2

Theo kinh nghiệm của tôi, bạn cũng nên thêm @Primary với một trong các DataSource đậu. Nếu không, nó sẽ ném NoUniqueBeanDefinitionException.

@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

Bạn có thể sử dụng lò xo của AbstractRoutingDataSource bằng cách mở rộng nó và trọng phương pháp determineCurrentLookupKey().

Xuân Cấu hình

Bạn có thể xác định riêng biệt datasource trong cấu hình mùa xuân.

<!-- 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> 

Associate nguồn dữ liệu với khách hàng:

Java

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

Về cơ bản, mỗi yêu cầu sẽ có bối cảnh của nó. Bạn có thể liên kết datasource với yêu cầu bằng cách sử dụng khóa được ánh xạ. Bạn có thể tìm thêm chi tiết tại đây 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> 

Như đã đề cập ở trên, chúng ta cần phải đưa ra tương ứng sessionfactory trong DaoImpl của bạn. Bạn không thể autowire SqlSessionTemplate trong lớp DaoImpl của bạn nếu bạn có nhiều hơn một sessionFactory. Đặt tên duy nhất cho mỗi nhà máy phiên và ánh xạ nó tới lớp DaoImpl tương ứng của bạn. Tất cả những gì bạn phải làm chỉ là tạo đối tượng cho SqlSessionTemplate với phương thức Setter trong lớp DaoImpl và bạn có thể thực hiện cuộc gọi db bằng cách sử dụng đối tượng sqlSessionTemplate như sau, this.sqlSessionTemplate.selectList ("ProcedureID", tham số);

Các vấn đề liên quan