`
dreamoftch
  • 浏览: 498308 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

spring读写分离

阅读更多

 

主要配置:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    http://www.springframework.org/schema/tx   
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
	<!-- 启动扫描component功能 -->
	<context:component-scan base-package="com.tch.test.springmvcmybatis" />
	<!-- viewResolver -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/pages/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<mvc:annotation-driven />
	<!-- 拦截器 -->
	<!-- <mvc:interceptors> 这里配置的拦截器相当于全局拦截器,只要有响应的后端处理器,就会经过该拦截器 <bean class="com.tch.test.springmvcmybatis.interceptor.MyInteceptor" 
		/> <mvc:interceptor> 只拦截匹配的路径 <mvc:mapping path="/namespace/*" /> <bean class="com.tch.test.springmvcmybatis.interceptor.MyInteceptor2" 
		/> </mvc:interceptor> </mvc:interceptors> -->

	<!-- 启动注解实物配置功能 -->
	<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
	<!-- 数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
	</bean>
	<!-- 数据源(slave) -->
	<bean id="slave_dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/test_slave"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
	</bean>

	<bean id="dynamicDataSource"
		class="com.tch.test.springmvcmybatis.datasource.DynamicDataSource">
		<property name="targetDataSources">
			<map>
				<entry key="slave" value-ref="slave_dataSource" />
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="dataSource" />
	</bean>

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

	<bean id="chooseDataSourceAdvice"
		class="com.tch.test.springmvcmybatis.datasource.ChooseDataSource"></bean>

	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED"
				rollback-for="java.lang.Exception" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>

	<aop:config expose-proxy="true"> <!-- proxy-target-class="true" -->
		<!-- 只对业务逻辑层实施事务 -->
		<aop:pointcut id="txPointcut"
			expression="execution(* com.tch.test.springmvcmybatis.service.*Service.*(..)) AND ! execution(* com.tch.test.springmvcmybatis.service.*Service.get*(..))" />
		<aop:pointcut id="determineReadOrWritePointcut"
			expression="execution(* com.tch.test.springmvcmybatis.service.*Service.get*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />

		<!-- 通过AOP切面实现读/写库选择 -->
		<aop:aspect order="-2147483648" ref="chooseDataSourceAdvice">
			<aop:around pointcut-ref="determineReadOrWritePointcut"
				method="determineReadOrWriteDB" />
		</aop:aspect>
	</aop:config>

	<!--读取数据库配置文件 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dynamicDataSource" />
		<!-- 如果mapper的xml文件名字和mapper接口的名字一致,并且在同一目录下(例如UserMapper.java和UserMapper.xml),可以不配置mapperLocations, -->
		<property name="mapperLocations" value="classpath:mybatis/**/*Mapper.xml" />
		<!-- 指定别名,在mapper的xml文件中可以使用别名(例如User/user来代表com.tch.test.spring_mybatis.entity.User),提高开发效率 -->
		<!-- <property name="typeAliasesPackage" value="com.tch.test.springmvcmybatis.bean" 
			/> -->
		<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 指定mapper接口包名,可以通过动态代理生成代理类,这样就可以在service层直接通过注入的方式进行dao操作了 -->
		<property name="basePackage" value="com.tch.test.springmvcmybatis.mapper" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
	</bean>

</beans>

 

 

说明:

 

当满足execution(* com.tch.test.springmvcmybatis.service.*Service.get*(..))切面的时候,切面会调用com.tch.test.springmvcmybatis.datasource.ChooseDataSource的determineReadOrWriteDB方法,

这个切面是around的类型,首先通过JdbcContextHolder.setSlave();将当前线程的数据源设为slave,最终获取到的dataSource就是slave_dataSource,从而达到对读操作使用slave_dataSource数据源的目的。

 

当满足execution(* com.tch.test.springmvcmybatis.service.*Service.*(..)) AND ! execution(* com.tch.test.springmvcmybatis.service.*Service.get*(..))切面的时候,

也就是增删改操作,需要事务,也就需要使用dataSource作为数据源,因为这时候没有调用JdbcContextHolder.setSlave(),此时,com.tch.test.springmvcmybatis.datasource.DynamicDataSource

就会使用默认的数据源defaultTargetDataSource,即dataSource作为数据源,从而达到目的。

 

这里面要注意的是,transactionManager和sqlSessionFactory都需要使用dynamicDataSource作为数据源,dynamicDataSource会根据determineCurrentLookupKey方法的返回值决定使用哪个数据源(slave_dataSource或者dataSource)

 

order="-2147483648" 表明优先级最高

 

 

分享到:
评论

相关推荐

    使用Spring实现读写分离(MySQL实现主从复制)

    在Spring框架下实现读写分离的核心在于通过AOP(面向切面编程)技术,在调用业务逻辑方法前根据一定的规则(如方法名前缀)来决定使用哪个数据源。具体实现包括以下几个步骤: 1. **定义动态数据源**:继承`...

    spring之mysql读写分离

    本文将深入探讨如何利用Spring AOP(面向切面编程)实现应用层的MySQL读写分离,并结合一主多从的配置来进行详细讲解。 首先,我们需要理解MySQL的主从复制机制。在主从复制中,数据的写操作(INSERT、UPDATE、...

    springaop多数据库读写分离

    以下将详细讲解如何利用Spring AOP来实现多数据库的读写分离。 首先,了解读写分离的基本概念。读写分离是指在一个数据库系统中,将读操作和写操作分配到不同的数据库服务器上,通常读操作远大于写操作,这样可以...

    spring mysql 读写分离

    Spring框架提供了对MySQL数据库读写分离的良好支持,使得开发者能够轻松地在应用中实现这一功能。 **1. 什么是读写分离** 读写分离是指在数据库系统中,将读操作和写操作分配到不同的服务器上执行,读操作通常发生...

    Spring+mysql读写分离

    本示例"Spring+MySQL+MyBatis+SpringMVC 读写分离"是针对这种策略的一个实现,旨在帮助开发者理解如何在实际项目中应用这一技术。下面将详细介绍这个Demo中的关键知识点。 首先,我们要理解什么是读写分离。读写...

    springboot实现mysql的读写分离的案例源码

    读写分离就是对于一条SQL该选择哪一个数据库去执行,至于谁来做选择数据库这件事,有两个,要么使用中间件帮我们做,要么程序自己做。一般来说,读写分离有两种实现方式。第一种是依靠中间件MyCat,也就是说应用程序...

    springBoot+mybatis读写分离(AOP)

    通过以上步骤,我们成功地在Spring Boot项目中实现了基于AOP的读写分离。这种方式不需要额外的插件,代码简洁,易于理解和维护。在高并发场景下,这种方案能够有效地减轻数据库压力,提高系统响应速度,是优化数据库...

    Spring配置动态数据源实现读写分离的方法

    在Spring框架中,实现数据库的读写分离是提高系统性能的一种常见策略,它可以将读操作和写操作分散到不同的数据源上,减轻主数据库的压力。本文将详细介绍如何利用Spring配置动态数据源来实现这一功能。 首先,我们...

    实现mysql读写分离+使用视频

    “14-使用Spring的AOP实现读写分离的原理.avi”探讨了如何利用Spring的面向切面编程(AOP)来动态地决定数据访问是在主库还是从库进行。AOP可以拦截数据库操作的请求,根据预设规则(比如只读操作指向从库,写操作...

    springboot 实现mysql读写分离

    2. **选择读写分离库管理组件**:SpringCloud的`Spring Cloud Config`或者`Hystrix`可以作为配置中心,用来动态获取读库和写库的地址。 3. **配置SpringBoot应用**: - 在`application.properties`或`application....

    在应用层通过spring特性解决数据库读写分离代码

    Spring框架提供了丰富的特性来支持这一实践,使得开发者能够在应用层轻松实现读写分离。下面将详细探讨如何利用Spring的特性来解决数据库读写分离的问题。 首先,我们需要理解读写分离的基本概念。读写分离是将...

    spring解决读写分离的方案有两种

    ### Spring 解决读写分离方案详解 #### 一、背景介绍 在现代应用程序开发中,尤其是在高并发场景下,数据库的读写操作往往是系统瓶颈之一。对于大多数应用场景来说,“读多写少”的特点非常显著,这意味着数据库的...

    在应用层透过spring解决数据库读写分离

    在应用层透过Spring解决数据库读写分离 数据库读写分离是指将数据库的读取和写入操作分开处理,以提高数据库的性能和可用性。在应用层解决数据库读写分离可以通过Spring框架来实现,本文将介绍如何使用Spring解决...

    springboot+mybatis+druid+redis实现数据库读写分离和缓存

    在现代Web应用开发中,数据库读写分离和缓存技术是提高系统性能和可扩展性的关键策略。本项目采用SpringBoot、MyBatis、Druid和Redis这四个核心技术来实现这一目标。以下将详细讲解这些组件如何协同工作,以及它们...

    springmvc mybatis 读写分离(一写多读)

    在现代的高并发Web应用中,数据库的读写分离是一种常见的优化策略,它可以提高系统的并发处理能力和稳定性。本文将深入探讨如何使用SpringMVC和MyBatis框架来实现读写分离,尤其是“一写多读”的模式。我们将讨论...

    MyBatis做读写分离

    ### MyBatis 实现读写分离 #### 一、读写分离的概念与优势 在数据库设计与应用领域,“读写分离”...通过以上步骤和技术细节,可以有效地利用 MyBatis 和 Spring 实现数据库的读写分离,进而提升系统的性能和稳定性。

    Spring实现数据库读写分离代码

    6. **Spring配置读写分离**:在Spring中,可以通过`DataSource`接口的实现类(如`AbstractRoutingDataSource`)来创建一个路由数据源,动态选择读库或写库。你需要定义两个或多个实际的数据源,并设置路由规则,比如...

    spring+springmvc+mybatis的整合以及数据库读写分离的测试

    本项目将这些框架进行了整合,并进行了数据库读写分离的配置,以提高系统的稳定性和性能。 首先,Spring框架作为基础,提供了强大的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented ...

    spring db读写分离

    通过spring实现的读写分离例子 当然,需要提前在db层配置好mysql的主从配置 mysql主从配置:http://blog.csdn.net/u013614451/article/details/48901541

Global site tag (gtag.js) - Google Analytics