需求:为减少数据加工所带来的压力,一个应用需要访问两个数据库地址。
首先配置文件的写法:
两个数据源的声明:写法上将数据源相同的部分写到一起,其他bean 标签继承他,便于管理
<bean id="parentDataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize"><value>5</value></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize"><value>30</value></property>
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 5 -->
<property name="initialPoolSize"><value>5</value></property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime"><value>0</value></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement"><value>5</value></property>
<!--每1200秒[20分钟]检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod"><value>1200</value></property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts"><value>30</value></property>
</bean>
<!-- 数据源1-->
<bean id="dataSource1" parent="parentDataSource" >
<property name="jdbcUrl" value="jdbc:mysql://192.168.1.5:3306/gjcx_adc_mgr?useUnicode=true&characterEncoding=utf-8"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 数据源2-->
<bean id="dataSource2" parent="parentDataSource" >
<property name="jdbcUrl" value="jdbc:mysql://120.194.181.10:3306/gjcx_adc_mgr?useUnicode=true&characterEncoding=utf-8"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
指定默认数据源
<!-- 默认配置datasource1 -->
<bean id="dataSource" class="com.running.crm.datasource.MultiDataSource">
<property name="dataSource">
<ref bean="dataSource1"/>
</property>
</bean>
接着sessionFactory配置不变,指定的还是dataSource,代码如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
......此处内容省略
</bean>
至于手写的MultiDataSource,代码如下:
package com.running.crm.datasource;
/**
*
*/
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author FanGang
*
*/
public class MultiDataSource implements DataSource,ApplicationContextAware {
private static final Log log = LogFactory.getLog(MultiDataSource.class);
private ApplicationContext applicationContext = null;
private DataSource dataSource = null;
public Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
public Connection getConnection(String arg0, String arg1)
throws SQLException {
return getDataSource().getConnection(arg0, arg1);
}
public PrintWriter getLogWriter() throws SQLException {
return getDataSource().getLogWriter();
}
public int getLoginTimeout() throws SQLException {
return getDataSource().getLoginTimeout();
}
public void setLogWriter(PrintWriter arg0) throws SQLException {
getDataSource().setLogWriter(arg0);
}
public void setLoginTimeout(int arg0) throws SQLException {
getDataSource().setLoginTimeout(arg0);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public DataSource getDataSource(String dataSourceName){
log.debug("dataSourceName:"+dataSourceName);
try{
if(dataSourceName==null||dataSourceName.equals("")){
return this.dataSource;
}
return (DataSource)this.applicationContext.getBean(dataSourceName);
}catch(NoSuchBeanDefinitionException ex){
throw new DaoException("There is not the dataSource <name:"+dataSourceName+"> in the applicationContext!");
}
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public DataSource getDataSource(){
String sp = SpObserver.getSp();
return getDataSource(sp);
}
}
里面有个自动捕捉异常类:DaoException.java
public class DaoException extends RuntimeException {
private static final long serialVersionUID = 7662715726329519089L;
public DaoException(String msg){
super(msg);
}
}
还有个对多线程实现非常好的方法:
public class SpObserver {
private static ThreadLocal local = new ThreadLocal();
public static void putSp(String sp) {
local.set(sp);
}
public static String getSp() {
return (String)local.get();
}
}
接着就可以在需要指定dataSource时,指定dataSource了。
比如在需要指定数据源2的方法里添加一条:
SpObserver.putSp("dataSource2");
但是我们这样一指定的话,每个方法执行时都是数据源2了,除非每个方法执行之前都加上上面那就话,这不是我们想要的结果,怎么办呢?可以添加一个过滤器,每次执行一个request时都将dataSource置为空,这样如果执行的方法没有指定数据源就用的是数据源1,指定了数据源就是数据源2.
过滤器filter写法:
package com.running.crm.datasource;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class filter implements Filter {
public filter() {
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
//String dataSource = httpRequest.getParameter("dataSource");
SpObserver.putSp("");
chain.doFilter(request, response);
}
public void destroy() {
}
}
过滤器配置:
<filter>
<filter-name>dsFilter</filter-name>
<filter-class>
com.running.crm.datasource.filter
</filter-class>
</filter>
<filter-mapping>
<filter-name>dsFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
这样就可以了。弊端就是每个方法都得手动添加java代码,但是好处也在于此,比如说一个应用新增导入操作频繁,数据量又大,查询缓慢,可以讲导入操作执行一个数据源,查询操作指向另一个数据源,这样就分开了。
还有种配置是直接更改配置文件。两个数据源配置,两个sessionFactory配置,然后将各个dao的指向进行手工的添加,看是用sessionFactory1,还是用2.其实就是通过更改dao的指向来实现多数据源,缺点就是增删改查是一体的,没法分开。
两种都实例亲测,可以通过。
以上文章取自网络,我记不得出处了。只为分享,不为其他。
分享到:
相关推荐
spring数据源配置
一个springboot的多数据配置,从mapper到controller完整的一个业务流程
spring 动态多数据源配置代码,本项目是maven项目,里面有完成的配资好的spring多数据源代码和配置文件。
Spring多数据源配置,支持mysql、oracle等多个数据源同时存在的情况
spring 配置多数据源
springboot多数据源配置
SSM(Spring+SpringMVC+MyBatis)多数据源配置框架,精简版
Spring Boot+Jpa多数据源配置Demo,可同时支持多种数据库,不同数据库,同时支持不同数据库的JdbcTemplate
Spring Boot使用spring-data-jpa配置Mysql多数据源,可用版本
基于注解的Spring多数据源配置和使用 前一段时间研究了一下spring多数据源的配置和使用,为了后期从多个数据源拉取数据定时进行数据分析和报表统计做准备。由于之前做过的项目都是单数据源的,没有遇到这种场景,...
通过简单的demo实现SpingBoot多数据源配置并动态切换多数据源
spring配置JNDI数据源
Spring Boot Mybatis 多数据源配置、Mybatis通用插件、MyBatis分页插件配置。
Spring多数据源配置_分布式数据 Tomcat服务器下的多数据源配置详情 一、环境及框架 Tomcat+spring+hibernate+jotm,还有就是struts、Oracle等 二、需求说明 系统里有2套不同网域的oracle数据库,之间的数据需要进行...
阐述spring的数据源配置
通过注解实现数据源的灵活切换
主要介绍了Spring3 整合MyBatis3 配置多数据源动态选择SqlSessionFactory详细教程,需要的朋友可以参考下
连接MYSQL数据库,SPRING配置文件示例。
1. 基于Aspectj实现动态数据源...6. 实现事务内切换数据源(支持原生Spring声明式事务哟,仅此一家),并支持多数据源事务回滚(有了它除了跨服务的事务你需要考虑分布式事务,其他都不需要,极大的减少了系统的复杂程度)