2 u010791853 u010791853 于 2017.01.16 11:00 提问

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
JE_GE   2017.01.16 11:04

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

u010791853
u010791853 项目现在不需要用中间件,简单的实现就行了。
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
spring-hibernate-mysql实现主从读写分离
原文:http://lujia35.iteye.com/blog/969466 介绍下mysql数据库读写分离在spring,hibernate框架下的配置。  1.mysql连接配置文件jdbc.properties  master.*.*表示主数据库连接参数,负责增,删,改;  slave.*.*表示从数据库连接参数,只负责读取;  jdbc.properties 
Spring+Hibernate+MySQL的主从分离/读写分离问题(1)
搭建后台API框架时遇到MySQL的主从(Master/Slave)分离问题,这里记录一下,遇到相似问题的小伙伴可以参考一下 首先简单说明一下问题由来,MySQL可以支持主从配置,实现数据备份和负载均衡等。 原理是主服务器通过复制把数据同步到从服务器上,可以支持一对多。 主服务器可以读和写,而从服务器只能读。
springboot +jpa 读写分离 遇到JavassistLazyInitializer及解决
最近做一个实验,用到springboot +jpa 用来操作mysql 读写分离,遇到一个问题,我在  使用dao 对象 public interface PersonRepository extends JpaRepository { } 中 person = personRepository.getOne(id); 的使用,出现 在返回对象中 增加一个 handler
spring hibernate配置切换数据源,实现读写分离
spring hibernate配置切换数据源,实现读写分离
SpringBoot 数据库读写分离
文章实现一主两从的续写分离:工程目录首先pom文件&amp;lt;!--排除默认日志框架--&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt; &amp;lt;excl...
Struts2.0+Spring2.0+Hibernate3.1登录及增删改查的完整演示示例 连载中...(三)
  好了,废话不多说了,接着今天早上我们的示例接着做完.  六、我们开始写Spring层:  1、 服务层接口IUsersService.java package org.login.service;import java.util.List;import org.login.vo.Users;@SuppressWarnings("unchecked")public interface I
使用Spring AOP实现MySQL数据库读写分离案例分析
一、前言分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量。在进行数据库读写分离的时候,我们首先要进行数据库的主从配置,最简单的是一台Master和一台Slave(大型网站系统的话,当然会很复杂,这里只是分析了最简单的情况)。通过主从配置主从数据库保持了相同的数据,我们在进行读操作的时候访问从数据库Slave,在
Spring+Hibernate进行双数据源测试Mysql集群读写分离
进行测试!环境就是SH框架、当然这只是一个简单的测试! 准备环境就是Spring框架跟Hibernate框架的整合! 然后在Spring配置文件中配置两个数据源、这里我采用的是从c3po数据源配置: 注:配置文件中的url里面要加"&"符号的话得这样写"&amp;" <beans xmlns="http://www.springframework.org/s
spring原理 struts2原理 hibernate原理 MyBatis原理 SpringMVC
spring原理 最核心的就是IOC,动态注入DI,利用java里的反射,让一个对象的创建不用new了,可以自动的生产。Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象。 Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用
Spring3整合Struts2+Hibernate 实现注册、数据库验证登陆
1 web.xml 与上一篇一样 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee