`

spring动态数据源的切换

阅读更多

目前项目框架很简单,spring+spring jdbc。

客户想,

1,临时添加一个数据源,然后切换到此数据源,进行操作。

2,能保证每个数据源的表结构是统一的。

 

解决思路,spring jdbc用到的是jdbctemplate, jdbctemplate需要一个datasource。实现一个datasource,

把“判断连接哪个数据源”的条件存在 ThreadLocal 中,这样在自己的datasource里,就可以取出来使用。而不用

在service和dao中该代码了。

 

1,在controller层中切换数据源。根据id在一个固定数据源()中查找已经储存的数据源信息,把需要切换的数据源和当前登录用户绑定起来(这里自己任意实现)。

 

 

public String changeDBSource(){
		if( !StringUtils.isBlank(id) ){
			dbSource = databaseSourceService.findDBSourceById(id);
			boolean b = false;
			if(b){
				//用户登录情况下,把dbSource与用户绑定。
			}else{
				//没有登录的情况下
				ActionContext.getContext().getSession().put(DatabaseObserver.DBKEY, dbSource);
			}
			DatabaseObserver.put(dbSource);
		}
		if( StringUtils.isBlank(dbSource.getId())){
			flag = "0";
		}else{
			flag = "1";
		}
		return "changeResult";
}

 附上DatabaseObserver的代码,很简单

 

public class DatabaseObserver {
    public static final String DBKEY = "dbkey";
    private static ThreadLocal <DatabaseSource> dbSource = new ThreadLocal<DatabaseSource>();    
    public static void put (DatabaseSource dbs)    
    {    
    	dbSource.set(dbs);    
    }    
    public static DatabaseSource get ()    
    {    
       return (DatabaseSource)dbSource.get();    
    }    
        
}   
 

 

 

2,与用户绑定后,用一个Filter过滤所有请求,把与用户绑定的数据源信息,通过DatabaseObserver写到ThreadLocal中。

 

 

public class ServerFilter extends HttpServlet implements Filter {   
    private static final long serialVersionUID = 6452049924844786456L;   
    private static FilterConfig filterConfig;   
    public void destroy() {   
        // TODO Auto-generated method stub   
    }   
    public void init(FilterConfig filterConfig) throws ServletException   
    {   
    }   
    public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain filterChain) throws IOException, ServletException {   
    	boolean b = false;
    	//如果用户登录了,则把数据源信息与用户绑定
    	HttpServletRequest httpRequest = (HttpServletRequest)request;
    	if(b==true){
    	}
    	else{
    		//没有登录的情况下
    		DatabaseSource dbSource = (DatabaseSource)httpRequest.getSession().getAttribute(DatabaseObserver.DBKEY);
    		if(dbSource!=null){
    			DatabaseObserver.put(dbSource);
    		}
    	}
        filterChain.doFilter(request, response);   
    }   
}
 

 

3,最后在自己实现的datasource中,根据Threadlocal的数据源信息,返回的datasource。

 

 

public class DataSourceWithCache implements DataSource { 
 
    private static Map<String, DataSource> sources = new HashMap<String, DataSource>(); 

    @Resource
    private IDatabaseSourceService databaseSourceService ;
    
    private DataSource getDataSource() { 
        DatabaseSource dbSource = DatabaseObserver.get();
        if( dbSource == null ){
        	List<DatabaseSource> dbList = databaseSourceService.findBDSourcesByCond(dbSource, 0	, 1);
        	if(dbList.size()>0){
        		dbSource = dbList.get(0);
        	}
            if( dbSource == null ){
            	return null;
            }
        }
        DataSource source = sources.get(dbSource.getId()); 
        if (source == null) { 
            source = createSource(dbSource);
            sources.put(dbSource.getId(), source); 
        } 
        return source; 
    } 
 
    private DataSource createSource( DatabaseSource dbSource  ) { 
        SingleConnectionDataSource source = new SingleConnectionDataSource(); 
        source.setDriverClassName("com.mysql.jdbc.Driver"); 
        source.setUrl(dbSource.getUrl()); 
        source.setUsername(dbSource.getUsername()); 
        source.setPassword(dbSource.getPassword()); 
        source.setSuppressClose(true); 
        return source; 
    } 
 
    @Override 
    public Connection getConnection() throws SQLException { 
        return getDataSource().getConnection(); 
    } 
 
    @Override 
    public Connection getConnection(String username, String password) 
            throws SQLException { 
        return getDataSource().getConnection(username, password); 
    } 
 
    @Override 
    public PrintWriter getLogWriter() throws SQLException { 
        return getDataSource().getLogWriter(); 
    } 
 
    @Override 
    public int getLoginTimeout() throws SQLException { 
        return getDataSource().getLoginTimeout(); 
    } 
 
    @Override 
    public void setLogWriter(PrintWriter out) throws SQLException { 
        getDataSource().setLogWriter(out); 
 
    } 
 
    @Override 
    public void setLoginTimeout(int seconds) throws SQLException { 
        getDataSource().setLoginTimeout(seconds); 
    } 
 
    @Override 
    public boolean isWrapperFor(Class<?> iface) throws SQLException { 
        return getDataSource().isWrapperFor(iface); 
    } 
 
    @Override 
    public <T> T unwrap(Class<T> iface) throws SQLException { 
        return getDataSource().unwrap(iface); 
    }

	public IDatabaseSourceService getDatabaseSourceService() {
		return databaseSourceService;
	}

	public void setDatabaseSourceService(IDatabaseSourceService databaseSourceService) {
		this.databaseSourceService = databaseSourceService;
	}
    
}
 

 

 

 

分享到:
评论

相关推荐

    使用注解配置实现Spring动态数据源切换

    使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...

    mybatis+spring实现动态切换数据源

    通过以上步骤,我们就实现了MyBatis与Spring配合下的动态数据源切换。这种机制有助于在多租户系统、读写分离或者高可用架构中灵活地管理数据库访问,提高了系统的可扩展性和灵活性。在实际应用中,还需要考虑数据源...

    真正意义的spring动态切换数据源源码

    1. **Spring的AbstractRoutingDataSource**:这是Spring提供的核心类,用于实现动态数据源切换。这个抽象类维护了一个数据源路由决策表,可以根据特定的规则(如事务上下文、线程局部变量等)来决定使用哪个数据源。...

    spring动态数据源+mybatis分库分表

    1. **Spring动态数据源**:Spring框架提供了动态数据源支持,允许我们在运行时根据需求切换或选择不同的数据源。这主要通过`AbstractRoutingDataSource`类实现,该类能够根据某种策略(如事务ID、用户名等)动态决定...

    spring 动态切换数据源

    以下将详细介绍如何实现Spring的动态数据源切换以及相关知识点。 1. **数据源配置** - `jdbc.properties`: 这个文件通常包含了数据库连接的相关配置,如URL、用户名、密码、驱动类名等。Spring通过`Properties`类...

    spring boot数据源切换demo

    在Spring Boot应用中,数据源切换是一个常见的需求,特别是在分布式系统或者微服务架构中,可能需要连接多个数据库来实现不同的业务功能。本示例“spring boot数据源切换demo”将展示如何在Spring Boot中集成MyBatis...

    Spring(AbstractRoutingDataSource)实现动态数据源切换示例

    【Spring 动态数据源切换】使用 `AbstractRoutingDataSource` 的详细实现在处理多数据库环境时,Spring 提供了一个强大的工具 `AbstractRoutingDataSource`,它允许我们根据特定条件动态地切换数据源。本文将深入...

    Spring动态切换多数据源Demo

    "Spring动态切换多数据源Demo"是一个示例项目,它展示了如何在Spring中实现灵活的数据源切换。 首先,我们需要了解Spring中的数据源。在Spring中,数据源(DataSource)是Java中定义的javax.sql.DataSource接口的...

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    - AOP切面的Java类,实现了方法执行前后的拦截和数据源切换。 - 数据源相关的Java配置类,用于配置Spring的DataSource和MybatisPlus。 - Mapper接口和对应的XML文件,定义数据库操作。 - 业务逻辑层的Java类,其中的...

    springboot-AOP实现多数据源动态切换(Druid连接池)

    - **动态数据源切换逻辑**:核心逻辑是在AOP切面的Advice中实现。当一个需要切换数据源的方法被调用时,通过反射或其他机制获取该方法上标注的数据源信息,然后根据这些信息从数据源池中获取对应的数据源,并将其...

    spring boot动态切换多数据源

    - 可以编写单元测试或集成测试,模拟不同场景下的数据源切换,确保功能正确无误。 - 使用日志记录数据源切换的过程,以便于调试和监控。 8. **最佳实践** - 避免在业务代码中直接切换数据源,最好通过服务层的...

    spring多数据源动态切换方案

    在企业级应用开发中,Spring框架的广泛使用使得...通过这种方式,我们可以灵活地处理复杂的数据源切换场景,适应不同业务的需求。在实际项目中,还需要考虑线程安全、异常处理、测试等方面的问题,确保系统稳定运行。

    spring动态切换数据源

    然后,定义一个数据源切换的抽象类或接口,用于封装切换逻辑: ```java public interface DataSourceSwitcher { DataSource switchDataSource(DataSourceType type); } ``` 接着,实现这个接口,基于Spring的`...

    Spring Boot多数据源(支持Spring声明式事务切换和回滚).pdf

    在本文中,我们将深入探讨如何实现动态数据源切换,支持Spring声明式事务管理,并讨论多数据源回滚策略。以下是对这些知识点的详细说明: 1. **动态数据源切换**: - 通过AspectJ实现数据源的动态切换,可以设置在...

    SpringBoot配置多数据源实现动态切换数据源

    本文将深入探讨如何在SpringBoot项目中配置多数据源,并实现数据源的动态切换,帮助你理解和掌握这一核心技能。 首先,我们理解"多数据源"的概念。在SpringBoot应用中,多数据源意味着系统能够连接并操作多个不同的...

    动态数据源实现spring

    在实际项目中,我们还可以结合Spring的事务管理、AOP切面等特性,实现更加复杂的数据源切换策略,以满足各种业务需求。 总的来说,动态数据源是Spring框架中的一项强大功能,它允许我们在不修改代码的情况下,根据...

    Springcloud 多数库 多数据源整合,查询动态切换数据库

    创建一个自定义的数据源切换注解,比如`@SwitchDataSource`,并在需要切换数据源的方法上使用。通过AspectJ的切面处理,我们可以在方法执行前后动态改变ThreadLocal中的数据源引用。 3. **Spring Cloud Config ...

    spring+druid+AtomikosDataSource实现多数据源切换及分布式事务控制

    综上所述,"spring+druid+AtomikosDataSource"的组合为开发者提供了一套强大的工具,用于实现多数据源切换和分布式事务控制。在实际项目中,通过合理的配置和编码,可以构建出高效、健壮的分布式系统。在`mult-table...

    SpringBoot+Atomikos+动态多数据源+事务+2种切换数据源的方式

    本主题将深入探讨如何利用SpringBoot结合Atomikos实现动态多数据源以及事务管理,并介绍两种切换数据源的方法。 首先,SpringBoot简化了传统Spring应用的初始化过程,它通过自动配置和starter包让开发者快速搭建...

    spring boot多数据源(AOP注解动态切换)

    3. **AOP实现动态数据源切换** 使用AOP(面向切面编程)注解,我们可以实现方法级别的数据源切换。创建一个`@Aspect`注解的类,定义一个环绕通知来切换数据源: ```java @Aspect @Component public class ...

Global site tag (gtag.js) - Google Analytics