主要配置:
<?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" 表明优先级最高
相关推荐
基于风光负荷不确定性的微电网两阶段鲁棒优化模型:投资与运行成本的综合考虑及CCG算法的Matlab+Yamilp+CPLEX求解方法,考虑风光负荷的不确定性,构建了微电网两阶段鲁棒优化容量配置模型,第一阶段目标函数为微电网投资成本,第二阶段目标函数为微电网的运行成本。 采用CCG算法求解。 包含非线性项的线性化处理。 程序代码matlab+yamilp+CPLEX ,核心关键词: 微电网; 两阶段鲁棒优化; 容量配置模型; CCG算法; 线性化处理; MATLAB; YAMILP; CPLEX 用分号分隔每个关键词的结果为: 微电网; 两阶段鲁棒优化; 容量配置模型; CCG算法; 线性化处理; MATLAB; Yamilp; CPLEX,微电网鲁棒优化模型:两阶段成本最小化与线性化处理
西门子S7-200PLC在Z35摇臂钻床控制系统中的应用与组态王组态设计研究,98西门子S7-200PLC和组态王组态Z35摇臂钻床控制系统组态设计PLC设计 ,西门子S7-200PLC; 组态王组态; 摇臂钻床控制系统; PLC设计,西门子S7-200PLC与组态王Z35摇臂钻床控制系统组态设计
烟花代码编程python满屏-10.排队接水——我直接把水吸过来.py
基于三菱PLC的喷灌控制系统设计及组态画面实现,No.393 三菱PLC组态王组态画面基于PLC的喷灌控制设计灌溉控制 ,基于三菱PLC; 喷灌控制设计; 组态王组态画面; 灌溉控制。,基于三菱PLC的喷灌控制设计:组态王组态画面应用
基于Dijkstra算法的路径规划Matlab代码:读取黑白色地图并实现图像上的路径规划示例,读取黑白色地图,在图片上进行路径规划matlab代码 路径规划算法基于读图识别的Dijkstra算法 随意设置坐标,规划路径 示例如下 ,读取地图; 路径规划算法; Dijkstra算法; 坐标设置; 规划路径,基于Dijkstra算法的Matlab黑白色地图路径规划代码
融合空间特征的债券图表数据文本检测方法研究.pdf
基于粒子群优化与遗传算法的高速列车横向悬挂模糊PID控制技术研究:s函数建模与仿真分析详解文件,基于粒子群 遗传算法的高速列车横向悬挂模糊PID控制-s函数搭建。 赠word详解文件 ,基于粒子群; 遗传算法; 高速列车横向悬挂; 模糊PID控制; s函数搭建,基于遗传算法的高速列车悬挂PID模糊控制的S函数构建方案
一种基于Retinex的非线性彩色图像增强算法.pdf
基于因式分解的逆合成孔径雷达三维成像技术及序列因子分解法研究,逆合成孔径雷达三维成像,因式分解法,序列因子分解法。 此部分只做了因式分解的工作,假设散射点已经准确提取并得到散射点坐标矩阵,利用因式分解恢复目标三维结构 ,逆合成孔径雷达三维成像; 因式分解法; 序列因子分解; 散射点提取; 散射点坐标矩阵; 恢复目标三维结构。,利用因式分解恢复三维结构:逆合成孔径雷达三维成像技术
MATLAB R2021b环境下深度学习驱动的车道线检测算法研究与应用,MATLAB环境下一种基于深度学习的车道线检测方法 算法运行环境为matlab r2021b,执行基于深度学习的车道线检测。 if batch ~= numBatches lastFrameIdx = miniBatchSize*batch; else 压缩包=数据+程序 ,核心关键词如下: MATLAB环境; 深度学习; 车道线检测; 算法运行环境; 批处理; 压缩包 以上关键词用分号分隔为: MATLAB环境; 深度学习; 车道线检测; 算法运行环境r2021b; 批处理(batch~numBatches); 压缩包(数据+程序) 注意:最后一个关键词“压缩包”并不是直接从您提供的信息中提炼出来的,而是根据您提到的“压缩包=数据+程序”这一句推断出来的。如果这不是您想要的核心关键词,请告诉我,我会进行相应的调整。,MATLAB深度学习车道线检测算法压缩包
西门子S7-200PLC在物料自动称量控制系统中的应用:基于称重配料混合程序的组态设计与王设计PLC程序设计,74基西门子S7-200PLC的物料自动称量控制系统称重配料物料混合程序组态设计组态设计组态王设计plc程序设计 ,核心关键词:西门子S7-200PLC;自动称量控制系统;物料混合程序;组态设计;组态王设计;PLC程序设计。,西门子S7-200PLC物料自动称量控制系统称重配料程序组态设计
优化无人机侦查与目标搜索路径规划:对未知区域进行覆盖并精确寻靶的Matlab代码解析与实践指南。,无人机覆盖搜索路径规划 无人机搜索目标路径规划 无人机侦查路径规划 对未知区域进行覆盖搜索,并且寻找目标 matlab代码有详细注释,可快速上手。 ,核心关键词:无人机; 覆盖搜索路径规划; 搜索目标路径规划; 侦查路径规划; 未知区域覆盖搜索; MATLAB代码注释。,**无人机未知区域覆盖搜索及目标路径规划Matlab代码详解**
shp格式,可直接导入arcgis使用
基于博途软件编程的11层电梯控制系统:文档齐全,优质售后保障的智能运行体验,基于PLC的单部11层电梯控制系统,采用博途软件编写提供画面,文档(含接线图,流程图,IO分配表)及优质的后服务。 最终运行效果,详见上方演示视频 ,核心关键词:PLC控制;11层电梯;博途软件;画面编写;文档资料;接线图;流程图;IO分配表;售后服务;演示视频。,"博途软件控制下的11层电梯系统,高效运行效果详见演示视频"
"飞剪追剪程序:PLC与伺服同步控制完整指南,适合新手学习与参考,包含PLC程序、触摸屏程序及CAD电路图纸",飞剪追剪程序plc程序伺服程序 同步控制 适合新手学习参考 包含PLC程序+触摸屏程序+CAD电路图纸。 ,飞剪追剪程序; PLC程序; 伺服程序; 同步控制; 新手学习参考; PLC程序+触摸屏程序; CAD电路图纸,适合新手的飞剪追剪程序全套教程:PLC+伺服同步控制
使用Matlab编程:无迹卡尔曼滤波算法(UKF)的编写及其在电池SOC估计中的应用,噪声系数自适应优化方案的研究。,使用matlab编写m脚本,编写无迹卡尔曼滤波算法(UKF)估计电池SOC,注释清晰。 卡尔曼滤波算法(EKF)锂电池SOC估计,噪声系数自适应 Matlab ,matlab; 无迹卡尔曼滤波算法(UKF); 电池SOC估计; 注释清晰; 噪声系数自适应。,Matlab无迹卡尔曼滤波(UKF)用于电池SOC估计的代码实现
Ansys LS-DYNA多孔延时起爆与重复起爆模拟的完整过程解析,Ansys ls_dyna多孔延时起爆,重复起爆模拟 全过程 ,Ansys;LS_dyna;多孔延时起爆;重复起爆模拟;全过程,Ansys LS-DYNA多孔延时重复起爆模拟全过程
FPGA驱动双目视觉系统:立体匹配、视差图与深度图生成技术的研究与应用,FPGA双目视觉 立体视觉 视差图 深度图 双目立体匹配sgm sgbm tang 20k 高云fpga usb摄像头采集图像 ,FPGA双目视觉;立体视觉;视差图;深度图;双目立体匹配sgm;sgbm;高云FPGA;USB摄像头图像采集。,基于FPGA的双目视觉系统:立体匹配与深度图生成
整个手套大盘的指数图如下.docx
基于AGV全覆盖移动避障的扫地机器人路径规划算法研究:深度优先搜索与随机碰撞对比,AGV全覆盖移动避障路径规划matlab代码 扫地机器人路径规划 第一类算法 全覆盖智能算法 %% 基于深度优先搜索算法的路径规划—扫地机器人移动仿真 % 返回深度优先搜索实现全覆盖的运行次数 % 将栅格模型的每一个栅格看成一个点 % 实际中栅格模型是连续的,在计算机处理时看作离散的 % 将栅格模型抽象为标识矩阵,矩阵对应位置的标记表示栅格对应位置的状态 第二对比算法 %% 随机碰撞的路径规划—扫地机器人移动仿真 % 返回深度优先搜索实现全覆盖的运行次数 % 将栅格模型的每一个栅格看成一个点 % 实际中栅格模型是连续的,在计算机处理时看作离散的 % 将栅格模型抽象为标识矩阵,矩阵对应位置的标记表示栅格对应位置的状态 ,核心关键词: 1. AGV全覆盖移动避障 2. 路径规划 3. Matlab代码 4. 扫地机器人路径规划 5. 第一类算法 6. 全覆盖智能算法 7. 深度优先搜索算法 8. 栅格模型 9. 标识矩阵 10. 随机碰撞的路径规划,"AGV全覆盖避障路径规划:Matlab代码实现与对比"