首页 > 其他分享 >ssm框架集成多数据源

ssm框架集成多数据源

时间:2022-12-06 15:46:36浏览次数:42  
标签:集成 DataSourceAnnotation 数据源 aop ssm import org public

 原理使用spring aop进行织入

 

 

1.创建3个类

 3 import java.lang.annotation.*;
 4 /**
 5  * 多数据源
 6  * @author mengxu
 7  * @version 2022-12-1
 8  */
 9 @Target({ElementType.TYPE, ElementType.METHOD})
10 @Retention(RetentionPolicy.RUNTIME)
11 @Documented
12 public @interface DataSourceAnnotation {
13 
14     String value();
15 
16     String primary = "primary";
17 
18     String secend= "secend";
19 
20 }

 

 2 
 3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 4 /**
 5  * 多数据源
 6  * @author mengxu
 7  * @version 2022-12-1
 8  */
 9 public class DynamicDataSource extends AbstractRoutingDataSource {
10 
11     /**
12      * 数据源标识,保存在线程变量中,避免多线程操作数据源时互相干扰
13      */
14     private static final ThreadLocal<String> key = new ThreadLocal<String>();
15 
16     @Override
17     protected Object determineCurrentLookupKey() {
18         return key.get();
19     }
20 
21     /**
22      * 设置数据源
23      *
24      * @param dataSource 数据源名称
25      */
26     public static void setDataSource(String dataSource) {
27         key.set(dataSource);
28     }
29 
30     /**
31      * 获取数据源
32      *
33      * @return
34      */
35     public static String getDatasource() {
36         return key.get();
37     }
38 
39     /**
40      * 清除数据源
41      */
42     public static void clearDataSource() {
43         key.remove();
44     }
45 
46 }

 

 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.aop.AfterReturningAdvice;
 6 import org.springframework.aop.MethodBeforeAdvice;
 7 import org.springframework.stereotype.Component;
 8 
 9 import java.lang.reflect.Method;
10 /**
11  * 多数据源
12  * @author mengxu
13  * @version 2022-12-1
14  */
15 @Component
16 public class DynamicDataSourceAspect implements MethodBeforeAdvice, AfterReturningAdvice {
17 
18     Logger log = LoggerFactory.getLogger(getClass());
19 
20     @Override
21     public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
22         //这里做一个判断,有使用DataSourceAnnotation注解时才关闭数据源,有一个主要的数据源,就没有必要每次都去关闭
23         if (method.isAnnotationPresent(DataSourceAnnotation.class)) {
24             DynamicDataSource.clearDataSource();
25             log.debug("数据源已关闭");
26         }
27     }
28 
29     /**
30      * 拦截目标方法,获取由@DataSourceAnnotation指定的数据源标识,设置到线程存储中以便切换数据源
31      */
32     @Override
33     public void before(Method method, Object[] objects, Object o) throws Throwable {
34         if (method.isAnnotationPresent(DataSourceAnnotation.class)) {
35             DataSourceAnnotation dataSourceAnnotation = method.getAnnotation(DataSourceAnnotation.class);
36             DynamicDataSource.setDataSource(dataSourceAnnotation.value());
37             log.debug("数据源切换为:" + DynamicDataSource.getDatasource());
38         }
39     }
40 }

2.在spring配置文件中配置命名空间

1:
xmlns:aop="http://www.springframework.org/schema/aop"
2:
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

 

 

 

 更改spring中的数据源 并配置aop的切面

 1 <!-- 动态数据源配置 -->
 2     <bean id="dataSource" class="com.jeeplus.modules.dynamic.DynamicDataSource">
 3         <property name="targetDataSources">
 4             <map key-type="java.lang.String">
 5                 <entry key="primary" value-ref="dataSourcePrimary"></entry>
 6                 <entry key="secend" value-ref="dataSourceSecend"></entry>
 7             </map>
 8         </property>
 9         <!-- 配置默认数据源 -->
10         <property name="defaultTargetDataSource" ref="dataSourcePrimary"></property>
11     </bean>

第一个数据源自行配置,跟第二个一样 12 <!--多数据源 第二个 数据源 --> 13 <bean id="dataSourceSecend" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 14 <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass --> 15 <property name="driverClassName" value="${jdbc.driver}" /> 16 <!-- 基本属性 url、user、password --> 17 <property name="url" value="${jdbc.urlsecend}" /> 18 <property name="username" value="${jdbc.usernamesecend}" /> 19 <property name="password" value="${jdbc.passwordsecend}" /> 20 <!-- 配置初始化大小、最小、最大 --> 21 <property name="initialSize" value="${jdbc.pool.init}" /> 22 <property name="minIdle" value="${jdbc.pool.minIdle}" /> 23 <property name="maxActive" value="${jdbc.pool.maxActive}" /> 24 <!-- 配置获取连接等待超时的时间 --> 25 <property name="maxWait" value="60000" /> 26 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> 27 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 28 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> 29 <property name="minEvictableIdleTimeMillis" value="300000" /> 30 <property name="validationQuery" value="${jdbc.testSql}" /> 31 <property name="testWhileIdle" value="true" /> 32 <property name="testOnBorrow" value="false" /> 33 <property name="testOnReturn" value="false" /> 34 <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) 35 <property name="poolPreparedStatements" value="true" /> 36 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> --> 37 <!-- 配置监控统计拦截的filters --> 38 <property name="filters" value="stat" /> 39 </bean> 40 <bean id="dynamicDataSourceAspect" class="com.jeeplus.modules.dynamic.DynamicDataSourceAspect"> 41 </bean> 42 <!--设置切面 com.test.service.*.impl.*()--> 43 <aop:config proxy-target-class="true"> 44 <aop:pointcut id="myPointcut" expression="execution(* com.xxx.modules.order.*.service.*.*(..))"/> 45 <aop:advisor advice-ref="dynamicDataSourceAspect" pointcut-ref="myPointcut" order="1"/> 46 <!--把事务控制在Service层--> 47 <!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" order="2"/>--> 48 </aop:config>

 

然后在方法上添加注解

@DataSourceAnnotation(DataSourceAnnotation.secend)
public Page<XXX> findPage(Page<xxx> page, XXX xxx) {
return super.findPage(page, xxx);
}

搞定啦!

 

标签:集成,DataSourceAnnotation,数据源,aop,ssm,import,org,public
From: https://www.cnblogs.com/aniymx/p/16955457.html

相关文章