Daniel Mao 2017-01-16 03:00 采纳率: 21.1%
浏览 1206

struts2+spring+hibernate 实现读写分离问题

数据库动态切换类:

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        System.out.println("===================切换数据源:" + DataSourceSwitcher.getDataSource());
        return DataSourceSwitcher.getDataSource();
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}

AOP切面类,设置数据源:

 @Component
@Aspect
@Order(0)
public class DataSourceAdvice {

    private static Logger logger = Logger.getLogger(DataSourceAdvice.class);

    @Before(("@annotation(com.lot.common.dataSource.DynamicDataSourceAnnotation)"))
    public void before(JoinPoint point) {
        try {
            // 获取数据源
            String dataSource = getDataSource(point);

            // 设置数据源
            logger.info("切换数据源到" + dataSource);
            DataSourceSwitcher.setDataSource(dataSource);
        } catch (Exception e) {
            logger.error("切换数据源失败...");
            logger.error(StringHandleUtils.getExceptionInfo(e));
        }
    }

    @After("@annotation(com.lot.common.dataSource.DynamicDataSourceAnnotation)")   //后置通知
    public void testAfter(JoinPoint point){
        try {
            // 获取数据源
            String dataSource = getDataSource(point);

            // 若数据源不是主库,则清空
            if(!DataSourceSwitcher.DATA_SOURCE_MASTER.equals(dataSource)) {
                logger.error("删除数据源" + dataSource + "成功...");
                DataSourceSwitcher.removeDataSource();
            }
        } catch (Exception e) {
            logger.error("删除数据源失败...");
            logger.error(StringHandleUtils.getExceptionInfo(e));
        }
    }

    @SuppressWarnings("rawtypes")
    private String getDataSource(JoinPoint point) {
        String dataSource = DataSourceSwitcher.DATA_SOURCE_MASTER;
        try{
            Class<?> className = point.getTarget().getClass();
            String methodName = point.getSignature().getName();
            Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
            Method method = className.getMethod(methodName, argClass);
            if (method.isAnnotationPresent(DynamicDataSourceAnnotation.class)) {
                DynamicDataSourceAnnotation annotation = method.getAnnotation(DynamicDataSourceAnnotation.class);
                dataSource = annotation.dataSource();
            }
        }catch(Exception e) {
            logger.error("获取数据源失败...");
            logger.error(StringHandleUtils.getExceptionInfo(e));
        }

        return dataSource;
    }
}

spring配置:

 <!-- master -->
    <bean id="master" class="com.lot.common.dataSource.DataSource" parent="commC3p0">
         <property name="driver" value="${master.datasource.driverClassName}" /> 
         <property name="driverUrl" value="${master.datasource.url}" /> 
         <property name="user" value="${master.datasource.username}"/> 
         <property name="password" value="${master.datasource.password}"/> 
     </bean>

    <!-- slave -->
    <bean id="slave" class="com.lot.common.dataSource.DataSource" parent="commC3p0">
        <property name="driver" value="${slave.datasource.driverClassName}" /> 
        <property name="driverUrl" value="${slave.datasource.url}" /> 
        <property name="user" value="${slave.datasource.username}"/> 
        <property name="password" value="${slave.datasource.password}"/> 
    </bean>

    <!-- 配置动态数据源 -->
    <bean id="dataSource" class="com.lot.common.dataSource.DynamicDataSource">  
        <property name="defaultTargetDataSource" ref="master"></property>
        <property name="targetDataSources">  
            <map key-type="java.lang.Object">  
                <entry value-ref="master" key="master"></entry>  
                <entry value-ref="slave" key="slave"></entry>
            </map>  
        </property>  
    </bean>

        <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>  
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>  
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>  
                <prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>  
                <prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>  
                <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>  
                <prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>  
                <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>  
                <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>  
                <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>  
                <prop key="hibernate.order_updates">${hibernate.order_updates}</prop>  
                <prop key="hibernate.query.factory_class">${hibernate.query.factory_class}</prop>  
                <prop key="hibernate.connection.isolation">${hibernate.connection.isolation}</prop> 

                <!-- 解决与weblogic的冲突 -->
                <prop key="hibernate.query.factory_class">${hibernate.query.factory_class}</prop>

                <prop key="hibernate.jdbc.batch_size">0</prop>   
            </props>
        </property>
        <property name="packagesToScan" value="com.entity"/>
    </bean>

    <!-- 定义事务管理器(声明式的事务)   -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 注解方式配置事务 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" />

数据源切换时在AOP之前执行了,导致数据源未切换。
图片说明

  • 写回答

1条回答

  • JE_GE 2017-01-16 03:04
    关注

    现在一般使用中间件mycat了吧

    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况