软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> Spring+Mybatis配置多数据库 -> 正文阅读
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制

[架构设计]Spring+Mybatis配置多数据库

  2016-04-02 20:55:22

目前有两种思路:
1.动态切换数据源,需要自定义一个数据源类继承自AbstractRoutingDataSource抽象类,这种方式有弊端,如果是并发系统中,当你把数据源改了,系统中所有的操作数据源都改了,即使你立马再改回去,还是有风险;
2.建立两套数据源,在spring加载Mapper时关联不同的数据源。
以下仅介绍第二种方式:
(1)新建两套数据源:
数据源一:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
	                    http://www.springframework.org/schema/aop     
	                    http://www.springframework.org/schema/aop/spring-aop-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">
  
    
	<!-- 配置DataSource数据源 -->
    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"  
         destroy-method="close">  
         <!-- 数据库驱动 -->  
         <property name="driverClass" value="${jdbc_driverClassName}" />  
         <!-- 相应驱动的jdbcUrl -->  
         <property name="jdbcUrl" value="${jdbc_url}" /> 
         <!-- 数据库的用户名 -->  
         <property name="username" value="${jdbc_username}" />  
         <!-- 数据库的密码 -->  
         <property name="password" value="${jdbc_password}" />  
       
       
         
        <!-- /** Maximum age of an unused connection before it is closed off. */ -->
		<!-- 设置分区个数。这个参数默认为1,建议3-4(根据特定应用程序而定)。
		 为了减少锁竞争和改善性能,从当前线程分区(thread-affinity)中获取一个connection,
		 也就是这个样子:partitions[Thread.currentThread().getId() % partitionCount]。
		 当拥有充足的短期(short-lived)的线程时候,这个参数设置越大,性能越好。
		当超过一定的阀值时,连接池的维护工作就可能对性能造成一定的负面影响(仅当分区上的connection使用耗尽时) -->
		<property name="partitionCount" value="${db.partitionCount}" />
		
		<!-- 设置每个分区含有connection最大个数。这个参数默认为2。如果小于2,BoneCP将设置为50。
		比如:partitionCount设置为3,maxConnectionPerPartition设置为5,你就会拥有总共15个connection。
		注意:BoneCP不会将这些connection一起创建出来,而是说在需要更多connection的时候从minConnectionsPerPartition参数开始逐步地增长connection数量。  -->
		<property name="maxConnectionsPerPartition" value="${db.maxConnectionsPerPartition}" />
		
		<!-- 设置每个分区含有connection最大小个数。这个参数默认为0。  -->
		<property name="minConnectionsPerPartition" value="${db.minConnectionsPerPartition}" />
		
		<!-- 设置分区中的connection增长数量。这个参数默认为1。
		当每个分区中的connection大约快用完时,BoneCP动态批量创建connection,
		这个属性控制一起创建多少个connection(不会大于maxConnectionsPerPartition)。
		注意:这个配置属于每个分区的设置。  -->
		<property name="acquireIncrement" value="${db.acquireIncrement}" />
		
		<!-- 设置连接池阀值。这个参数默认为20。如果小于0或是大于100,BoneCP将设置为20。
		连接池观察线程(PoolWatchThread)试图为每个分区维护一定数量的可用connection。
		这个数量趋于maxConnectionPerPartition和minConnectionPerPartition之间。这个参数是以百分比的形式来计算的。
		例如:设置为20,下面的条件如果成立:Free Connections / MaxConnections < poolAvailabilityThreshold;就会创建出新的connection。
		换句话来说连接池为每个分区至少维持20%数量的可用connection。
		设置为0时,每当需要connection的时候,连接池就要重新创建新connection,这个时候可能导致应用程序可能会为了获得新connection而小等一会。  -->
		<property name="poolAvailabilityThreshold" value="${db.poolAvailabilityThreshold}" />
		
		<!-- 设置获取connection超时的时间。这个参数默认为Long.MAX_VALUE;单位:毫秒。
		在调用getConnection获取connection时,获取时间超过了这个参数,就视为超时并报异常。  -->
		<property name="connectionTimeoutInMs" value="${db.connectionTimeoutInMs}" />
		
		<!-- /** A connection older than maxConnectionAge will be destroyed and purged from the pool. */ -->
		<!-- 设置connection的存活时间。这个参数默认为0,单位:毫秒。设置为0该功能失效。
		通过ConnectionMaxAgeThread观察每个分区中的connection,不管connection是否空闲,
		如果这个connection距离创建的时间大于这个参数就会被清除。当前正在使用的connection不受影响,直到返回到连接池再做处理。 -->
		<!-- 48小时关闭一个链接 -->
		<property name="maxConnectionAgeInSeconds" value="${db.maxConnectionAgeInSeconds}" />
		
		<!-- /** SQL statement to use for keep-alive/test of connection. */ -->
		<property name="connectionTestStatement" value="${db.connectionTestStatement}" />
		
		<!-- 设置connection的空闲存活时间。这个参数默认为60,单位:分钟。设置为0该功能失效。
		通过ConnectionTesterThread观察每个分区中的connection,如果这个connection距离最后使用的时间大于这个参数就会被清除。
		注意:这个参数仅和idleConnectionTestPeriodInSeconds搭配使用,而且不要在这里设置任何挑衅的参数!  -->
		<!-- 1小时回收空闲链接 -->
		<property name="idleMaxAgeInMinutes" value="${db.idleMaxAgeInMinutes}" />
		
		<!-- /** Connections older than this are sent a keep-alive statement. */ -->
		<!-- 设置测试connection的间隔时间。这个参数默认为240*60,单位:分钟。设置为0该功能失效。
		通过ConnectionTesterThread观察每个分区中的connection, 
		如果这个connection距离最后使用的时间大于这个参数并且距离上一次测试的时间大于这个参数就会向数据库发送一条测试语句,如果执行失败则将这个connection清除。
		注意:这个值仅和idleMaxAge搭配使用,而且不要在这里设置任何挑衅的参数! -->
		<!-- 4小时检测一次空闲链接 -->
		<property name="idleConnectionTestPeriodInMinutes" value="${db.idleConnectionTestPeriodInMinutes}" />
		
		<!-- /** After attempting to acquire a connection and failing, try to connect these many times before giving up. */ -->
		<!-- 设置重新获取连接的次数。这个参数默认为5。
		获取某个connection失败之后会多次尝试重新连接,如果在这几次还是失败则放弃。  -->
		<property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" />
		
		<!-- 设置重新获取连接的次数间隔时间。这个参数默认为7000,单位:毫秒。如果小于等于0,BoneCP将设置为1000。
		获取connection失败之后再次尝试获取connection的间隔时间。  -->
		<property name="acquireRetryDelayInMs" value="${db.acquireRetryDelayInMs}" />
		
		<!-- 设置连接池初始化功能。这个参数默认为false。
		设置为true,连接池将会初始化为空,直到获取第一个connection。  -->
		<property name="lazyInit" value="${db.lazyInit}" />
		
		<!-- 设置是否关闭JMX功能。这个参数默认为false。  -->
		<property name="disableJMX" value="${db.disableJMX}" />
		
		<!-- 设置连接池名字。用于当作JMX和助手线程名字的后缀。  -->
		<property name="poolName" value="${db.poolName}" />
		
		<!-- /** Min no of prepared statements to cache. */ -->
		<!-- 设置statement缓存个数。这个参数默认为0。  -->
		<property name="statementsCacheSize" value="${db.statementsCacheSize}" />
		
		<!-- 设置是否开启记录SQL语句功能。这个参数默认是false。
		将执行的SQL记录到日志里面(包括参数值)。  -->
		<property name="logStatementsEnabled" value="${db.logStatementsEnabled}" />
		
		<!-- 设置执行SQL的超时时间。这个参数默认为0;单位:毫秒。
		当查询语句执行的时间超过这个参数,执行的情况就会被记录到日志中。
		设置为0时,该功能失效。   -->
		<property name="queryExecuteTimeLimitInMs" value="${db.queryExecuteTimeLimit}" />
     </bean>
	
	<!-- 对数据源进行事务管理 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>      
		
	<!-- 配置SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		
		<!-- mapper和resultmap配置路径 -->
		<property name="mapperLocations">
			<list>                
				<value>classpath:mapper/*Mapper.xml</value>
			</list>
		</property>
	</bean>        

	<tx:annotation-driven  transaction-manager="transactionManager" />  

</beans>

数据源二:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	                    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
	                    http://www.springframework.org/schema/aop     
	                    http://www.springframework.org/schema/aop/spring-aop-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">
  
    
	<!-- 配置DataSource数据源 -->
    <bean id="dataSource2" class="com.jolbox.bonecp.BoneCPDataSource"  
         destroy-method="close">  
         <!-- 数据库驱动 -->  
         <property name="driverClass" value="${jdbc_driverClassName}" />  
         <!-- 相应驱动的jdbcUrl -->  
         <property name="jdbcUrl" value="${jdbc_url2}" /> 
         <!-- 数据库的用户名 -->  
         <property name="username" value="${jdbc_username2}" />  
         <!-- 数据库的密码 -->  
         <property name="password" value="${jdbc_password2}" />  
       
       
         
        <!-- /** Maximum age of an unused connection before it is closed off. */ -->
		<!-- 设置分区个数。这个参数默认为1,建议3-4(根据特定应用程序而定)。
		 为了减少锁竞争和改善性能,从当前线程分区(thread-affinity)中获取一个connection,
		 也就是这个样子:partitions[Thread.currentThread().getId() % partitionCount]。
		 当拥有充足的短期(short-lived)的线程时候,这个参数设置越大,性能越好。
		当超过一定的阀值时,连接池的维护工作就可能对性能造成一定的负面影响(仅当分区上的connection使用耗尽时) -->
		<property name="partitionCount" value="${db.partitionCount}" />
		
		<!-- 设置每个分区含有connection最大个数。这个参数默认为2。如果小于2,BoneCP将设置为50。
		比如:partitionCount设置为3,maxConnectionPerPartition设置为5,你就会拥有总共15个connection。
		注意:BoneCP不会将这些connection一起创建出来,而是说在需要更多connection的时候从minConnectionsPerPartition参数开始逐步地增长connection数量。  -->
		<property name="maxConnectionsPerPartition" value="${db.maxConnectionsPerPartition}" />
		
		<!-- 设置每个分区含有connection最大小个数。这个参数默认为0。  -->
		<property name="minConnectionsPerPartition" value="${db.minConnectionsPerPartition}" />
		
		<!-- 设置分区中的connection增长数量。这个参数默认为1。
		当每个分区中的connection大约快用完时,BoneCP动态批量创建connection,
		这个属性控制一起创建多少个connection(不会大于maxConnectionsPerPartition)。
		注意:这个配置属于每个分区的设置。  -->
		<property name="acquireIncrement" value="${db.acquireIncrement}" />
		
		<!-- 设置连接池阀值。这个参数默认为20。如果小于0或是大于100,BoneCP将设置为20。
		连接池观察线程(PoolWatchThread)试图为每个分区维护一定数量的可用connection。
		这个数量趋于maxConnectionPerPartition和minConnectionPerPartition之间。这个参数是以百分比的形式来计算的。
		例如:设置为20,下面的条件如果成立:Free Connections / MaxConnections < poolAvailabilityThreshold;就会创建出新的connection。
		换句话来说连接池为每个分区至少维持20%数量的可用connection。
		设置为0时,每当需要connection的时候,连接池就要重新创建新connection,这个时候可能导致应用程序可能会为了获得新connection而小等一会。  -->
		<property name="poolAvailabilityThreshold" value="${db.poolAvailabilityThreshold}" />
		
		<!-- 设置获取connection超时的时间。这个参数默认为Long.MAX_VALUE;单位:毫秒。
		在调用getConnection获取connection时,获取时间超过了这个参数,就视为超时并报异常。  -->
		<property name="connectionTimeoutInMs" value="${db.connectionTimeoutInMs}" />
		
		<!-- /** A connection older than maxConnectionAge will be destroyed and purged from the pool. */ -->
		<!-- 设置connection的存活时间。这个参数默认为0,单位:毫秒。设置为0该功能失效。
		通过ConnectionMaxAgeThread观察每个分区中的connection,不管connection是否空闲,
		如果这个connection距离创建的时间大于这个参数就会被清除。当前正在使用的connection不受影响,直到返回到连接池再做处理。 -->
		<!-- 48小时关闭一个链接 -->
		<property name="maxConnectionAgeInSeconds" value="${db.maxConnectionAgeInSeconds}" />
		
		<!-- /** SQL statement to use for keep-alive/test of connection. */ -->
		<property name="connectionTestStatement" value="${db.connectionTestStatement}" />
		
		<!-- 设置connection的空闲存活时间。这个参数默认为60,单位:分钟。设置为0该功能失效。
		通过ConnectionTesterThread观察每个分区中的connection,如果这个connection距离最后使用的时间大于这个参数就会被清除。
		注意:这个参数仅和idleConnectionTestPeriodInSeconds搭配使用,而且不要在这里设置任何挑衅的参数!  -->
		<!-- 1小时回收空闲链接 -->
		<property name="idleMaxAgeInMinutes" value="${db.idleMaxAgeInMinutes}" />
		
		<!-- /** Connections older than this are sent a keep-alive statement. */ -->
		<!-- 设置测试connection的间隔时间。这个参数默认为240*60,单位:分钟。设置为0该功能失效。
		通过ConnectionTesterThread观察每个分区中的connection, 
		如果这个connection距离最后使用的时间大于这个参数并且距离上一次测试的时间大于这个参数就会向数据库发送一条测试语句,如果执行失败则将这个connection清除。
		注意:这个值仅和idleMaxAge搭配使用,而且不要在这里设置任何挑衅的参数! -->
		<!-- 4小时检测一次空闲链接 -->
		<property name="idleConnectionTestPeriodInMinutes" value="${db.idleConnectionTestPeriodInMinutes}" />
		
		<!-- /** After attempting to acquire a connection and failing, try to connect these many times before giving up. */ -->
		<!-- 设置重新获取连接的次数。这个参数默认为5。
		获取某个connection失败之后会多次尝试重新连接,如果在这几次还是失败则放弃。  -->
		<property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" />
		
		<!-- 设置重新获取连接的次数间隔时间。这个参数默认为7000,单位:毫秒。如果小于等于0,BoneCP将设置为1000。
		获取connection失败之后再次尝试获取connection的间隔时间。  -->
		<property name="acquireRetryDelayInMs" value="${db.acquireRetryDelayInMs}" />
		
		<!-- 设置连接池初始化功能。这个参数默认为false。
		设置为true,连接池将会初始化为空,直到获取第一个connection。  -->
		<property name="lazyInit" value="${db.lazyInit}" />
		
		<!-- 设置是否关闭JMX功能。这个参数默认为false。  -->
		<property name="disableJMX" value="${db.disableJMX}" />
		
		<!-- 设置连接池名字。用于当作JMX和助手线程名字的后缀。  -->
		<property name="poolName" value="${db.poolName}" />
		
		<!-- /** Min no of prepared statements to cache. */ -->
		<!-- 设置statement缓存个数。这个参数默认为0。  -->
		<property name="statementsCacheSize" value="${db.statementsCacheSize}" />
		
		<!-- 设置是否开启记录SQL语句功能。这个参数默认是false。
		将执行的SQL记录到日志里面(包括参数值)。  -->
		<property name="logStatementsEnabled" value="${db.logStatementsEnabled}" />
		
		<!-- 设置执行SQL的超时时间。这个参数默认为0;单位:毫秒。
		当查询语句执行的时间超过这个参数,执行的情况就会被记录到日志中。
		设置为0时,该功能失效。   -->
		<property name="queryExecuteTimeLimitInMs" value="${db.queryExecuteTimeLimit}" />
     </bean>
	
	<!-- 对数据源进行事务管理 -->
	<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource2" />
	</bean>      
		
	<!-- 配置SqlSessionFactoryBean -->
	<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource2" />     
		
		<!-- mapper和resultmap配置路径 -->
		<property name="mapperLocations">
			<list>                
				<value>classpath:mapper2/*Mapper.xml</value>
			</list>
		</property>
	</bean>        

	<tx:annotation-driven  transaction-manager="transactionManager2" />  

</beans>
注意:sqlSessionFactory2关联的Mapper.xml的映射地址;
(2)在spring中扫描Mapper.java文件:
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.alan.test.mapper" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.alan.test.mapper2" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"></property>
	</bean>

注意:关联不同的包和sqlSessionFactory,这里使用sqlSessionFactoryBeanName,而不是sqlSessionFactory;
如果只是关联一个Mapper,则可以使用如下方式

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="com.alan.test.mapper2.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory2" />
</bean>

注意:mapper和mapper2中不能有相同的类名,因为扫描的时候会根据类名来新建bean托管给spring。

其它的Dao层等不用修改,在需要调用新数据库的地方,调用对应的mapper就可以了。


上一篇文章      下一篇文章      查看所有文章
2016-04-02 20:54:52  
360图书馆 论文大全 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 人民的名义 人民的名义在线看 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图
中国文化英文 多播视频 装修知识库
2017-4-29 9:37:01
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --