SSM java切换数据源 实现读写分离

3 篇文章 0 订阅
 
jar包
<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
配置数据源(用阿里的druid管理数据源)
<bean id="db1" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
 
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
 
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
 
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
 
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
 
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
 
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
</bean>
<bean id="dataSource" class="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="db1" value-ref="db1"/>
              <entry key="db2" value-ref="db2"/>//db2跟上面db1一样配置
            </map>
        </property>
        <!--默认数据源-->
        <property name="defaultTargetDataSource" ref="db1"/>
    </bean>
 
配置session
    <bean id="sqlSessionFactory"
        class="cn.zj.pubinfo.comm.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.zjpii.wanbao.entity" />
        <property name="typeAliasesSuperType" value="cn.zj.pubinfo.comm.core.entity.BaseEntity" />
        <property name="mapperLocations" value="classpath*:/mappings/**/*.xml" />
        <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
        
       这里是配置了分页的插件,没用到不用配
        <property name="plugins">
            <array>
            <!-- 分页 -->
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties" >
                        <value>
                            dialect=oracle
                            offsetAsPageNum=true
                            rowBoundsWithCount=true
                            pageSizeZero=truereasonable=false
                            reasonable=true
                           <!--  params=pageNum=pageHelperStart;pageSize=pageHelperRows; -->
                            supportMethodsArguments=false
                        </value>
                    </property>
                </bean>
            </array>
        </property> 
    </bean>
配置事务


    <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 -->
    <context:component-scan base-package="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb,com.zjpii.wanbao.service.impl,cn.zj.pubinfo.comm.mybatis.spring.aspect"><!-- base-package 
            如果多个,用“,”分隔 -->
        <context:exclude-filter type="annotation"
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- 定义事务 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

 
 

实现AbstractRoutingDataSource类 作为数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        String dbKey=DataSourceHolder.getDataSources();
        return dbKey;
    }
}
 
用ThreadLcoal管理当前数据源
public class DataSourceHolder {
    private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();
 
    public static void setDataSources(String dataSource) {
        dataSources.set(dataSource);
    }
 
    public static String getDataSources() {
        return dataSources.get();
    }
}
 
AOP支持
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
 
/**
 * 动态切换数据源切面
 */
@Component
@Aspect
@Order(-1)
public class DynamicDataSourceInterceptor {
 
    @Around(value = "@annotation(switchDB)")
    public Object process(ProceedingJoinPoint point, SwitchDB switchDB) throws Throwable {
        Object returnValue;
        try {
            DataSourceHolder.setDataSources(switchDB.dbID());
            returnValue = point.proceed(point.getArgs());
        } finally {
            DataSourceHolder.setDataSources(null);
        }
 
        return returnValue;
    }
}
 
注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 动态切换数据源
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SwitchDB {
 
    String dbID();
}
 
在spring里面扫描
<aop:aspectj-autoproxy proxy-target-class="true" />
<context:component-scan base-package="cn.zj.pubinfo.comm.mybatis.spring.dynamicdb"><!-- base-package 
如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
 
在service层方法中添加注解
@SwitchDB(dbID = "db1") 
public List<String> find() {
return userDao.find();
}
db1已经在数据源配置中配置
现在即可以切换数据源进行操作了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值