1. 程式人生 > >ssm中使用兩個資料庫,通過註解方式切換資料來源

ssm中使用兩個資料庫,通過註解方式切換資料來源

1、在配置檔案jdbc.properties中,配置兩個資料庫例如:


jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://192.168.0.154:1433;DatabaseName=PenalizeAPI_UP
jdbc.username=chn
jdbc.password=ChangNeng!2369

jdbc.driverClassName_test=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url_test=jdbc:sqlserver://192.168.0.160:1433;databaseName=Penalize20170416
jdbc.username_test=chn
jdbc.password_test=Changneng12369


druid.initialSize=50
druid.maxActive=100
druid.minIdle=15

2、在spring-Mybatis.xml中載入jdbc檔案,配置datasource。


<!-- scanner jdbc properties  -->
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>

<!-- 連線另一個數據庫 -->
<bean id="dateSource_second" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 資料庫驅動 -->
        <property name="driverClassName" value="${jdbc.driverClassName_test}" />
        <!-- 連線URL串 -->
        <property name="url" value="${jdbc.url_test}" />
        <!-- 連線使用者名稱 -->
        <property name="username" value="${jdbc.username_test}" />
        <!-- 連線密碼 -->
        <property name="password" value="${jdbc.password_test}" />
        
        <!-- 配置初始化大小 -->  
        <property name="initialSize" value="${druid.initialSize}" />  
        <!-- 配置初始化最大 連線數 -->  
        <property name="maxActive" value="${druid.maxActive}" />  
        <!-- 配置初始化最小連線數 -->  
        <property name="minIdle" value="${druid.minIdle}" />  
        <!-- 配置獲取連線等待超時的時間 -->  
        <property name="maxWait" value="60000" />  
        <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 -->  
        <property name="timeBetweenEvictionRunsMillis" value="20000" />  
        <!-- 配置一個連線在池中最小生存的時間,單位是毫秒 -->  
        <property name="minEvictableIdleTimeMillis" value="300000" />  
        <!-- 檢測連線是否有效的SQL -->  
        <property name="validationQuery" value="SELECT 'x' " />  
        <property name="testWhileIdle" value="false" />  
        <property name="testOnBorrow" value="false" />  
        <property name="testOnReturn" value="false" />  
        <!-- MySQL不需要做PSCache,只有Oracle/DB2/SQL Server之類支援遊標的資料庫才需要配置成true -->  
        <property name="poolPreparedStatements" value="false" />  
        <!-- 如果是Oracle/DB2/SQL Server之類支援遊標的資料庫需要加上一下配置 -->  
        <property name="maxPoolPreparedStatementPerConnectionSize" value="50" /> 
        <!-- durib監控,否則不顯示資料 -->
        <property name="filters" value="stat"></property>
</bean>
 
   <!--資料庫連線-->  
    <bean id="dataSource_first" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   
      <!-- 資料庫驅動 -->
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <!-- 連線URL串 -->
        <property name="url" value="${jdbc.url}" />
        <!-- 連線使用者名稱 -->
        <property name="username" value="${jdbc.username}" />
        <!-- 連線密碼 -->
        <property name="password" value="${jdbc.password}" />
        
        <!-- 配置初始化大小 -->  
        <property name="initialSize" value="${druid.initialSize}" />  
        <!-- 配置初始化最大 連線數 -->  
        <property name="maxActive" value="${druid.maxActive}" />  
        <!-- 配置初始化最小連線數 -->  
        <property name="minIdle" value="${druid.minIdle}" />  
  
    </bean> 

<!-- 下面的是切換資料庫的自定義類 -->
<bean id="multipleDataSource" class="com.changneng.penalize.business.datasource.MultipleDataSource">
<property name="defaultTargetDataSource" ref="dataSource_first"></property>
<property name="targetDataSources">
<map>
<entry key="dataSource_first" value-ref="dataSource_first"></entry>
<entry key="dateSource_second" value-ref="dateSource_second"></entry>
</map>
</property>
</bean>




<!-- myBatis mapping檔案 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipleDataSource" />
<!-- 指定MyBatis配置檔案 -->
       <property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 自動掃描entity目錄, 省掉Configuration.xml裡的手工配置 -->
<property name="mapperLocations" value="classpath*:com/changneng/penalize/business/mapper/*.xml" />
</bean>

<!-- 自動掃描dao包下的所有類 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.changneng.penalize.business.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>


<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="multipleDataSource" />
</bean>


<!-- 註解方式配置事物 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

</beans>
3、自定義資料庫切換類

public class MultipleDataSource extends AbstractRoutingDataSource {


private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();

public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}

@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}

}

4、設定註解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface DataSwitch {
String dataSource() default "";
}

5、編寫AOP類

@Aspect
@Component
public class DataSwitchAop {
//@Pointcut()
//@Pointcut("execution(public * com.changneng.penalize.business.service.impl.*(..))")
public void execute(){
}

@Before("@annotation(com.changneng.penalize.business.aop.DataSwitch)")
public void dataSwitch(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();

MethodSignature methodSignature =(MethodSignature) signature;
   Method method = methodSignature.getMethod();
   DataSwitch data = null;
   if(method!=null){
   data = method.getAnnotation(DataSwitch.class);
   }
   String dataSource = data.dataSource();
System.out.println("datasource...."+dataSource);
if(dataSource!=null){
MultipleDataSource.setDataSourceKey(dataSource);
}
}
}

6、在哪個需要切換資料庫的Service中加上註解例如:

//切換資料庫
@DataSwitch(dataSource="dateSource_second")
public int getBaseID(String areaCode,String enterPriseID){
//MultipleDataSource.setDataSourceKey("dateSource_second");
return dbUtilMapper.selectBaseID(areaCode,enterPriseID);
}