SpringBoot+Mybatis中使用动态代理方式动态切换datasource
来源:互联网 发布:java项目遇到的难题 编辑:程序博客网 时间:2024/05/22 12:13
背景:
项目原先只有一个数据库(开发工作已基本完成),后来又添加了一个库,两个库数据结构一致,查询逻辑基本一致,只是数据对应的年份不一样,客户提出的需求是根据可以自主选择查询不同年份的数据,而默认框架实现里没有多数据源的方法。
项目基础框架:
SpringBoot+Mybatis
解决方案:
有两套系统同时使用这两个库,另外一个系统的同学的解决方案是另开一个服务器,直接使用不同的数据库配置。
我觉得这样干不符合我的审美,考虑通过前台在用户选择年份后,固定传递年份参数,后台根据此参数动态切换数据源的方式实现。
实现方式如下:
1、定义一个注解TimeCare,对需要动态切换的controller或method进行标注(即带有此注解的controller或者方法在执行时需要根据年份动态切换数据源,其他的使用默认数据源)。
@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface TimeCare { }
2、定义切面,对有TimeCare注解的执行过程进行拦截。
@Around(value="@within(co.lewis.aspect.TimeCare)") public Object arround(ProceedingJoinPoint pjp) throws Throwable { HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); String year=request.getParameter("year"); if(year==null||year.trim().length()==0){ year= ConstParameters.default_last_year; } DataSourceWrapper.resetDataSource(year);//设置年份,此处使用一个ThreadLocal对象存储年份数据 Object ret=pjp.proceed(); DataSourceWrapper.resetDataSource(null);//将年份信息重新置空 return ret; }
3、定义一个动态代理类,代替默认的DataSource实现类
@Configuration@EnableConfigurationProperties({DataSource2015.class.......})//注册数据源1、数据源2......public class DataSourceWrapper implements InvocationHandler { public static void resetDataSource(String key){ year.set(key); } private static ThreadLocal<String> year=new ThreadLocal<>(); @Bean(name = "dataSource",destroyMethod = "close") //注册datasource bean public DataSource getDataSource(){ return (DataSource) this.bind();//生成代理对象 } public Object bind(){ return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{DataSource.class,AutoCloseable.class, CommonDataSource.class, Wrapper.class},this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(detemine(),args);//在调用数据源内部方法时动态决定使用哪一个数据源 } DataSource detemine(){}}
4、在application.properties文件中添加数据源配置
dataSource2015.url=jdbc:oracle:thin:@111.111.111.111:1521/ORCldataSource2015.username=username1dataSource2015.password=passwd1dataSource2015.driver-class-name=oracle.jdbc.driver.OracleDriverdataSource2016.url=jdbc:oracle:thin:@111.111.111.112:1521/ORCldataSource2016.username=username2dataSource2016.password=passwd2dataSource2016.driver-class-name=oracle.jdbc.driver.OracleDriver
5、实现数据源注册类DataSource2015、DataSource2016等(略)
如此,便实现了在不做太大改动的情况下使用多个数据源。即使以后又添加新的数据库,也可以通过简单添加新的DataSource注册类的方式实现新数据库查询。
3 0
- SpringBoot+Mybatis中使用动态代理方式动态切换datasource
- 实现 spring + mybatis 动态切换 datasource
- Datasource动态切换
- Mybatis实现Mapper动态代理方式
- Mybatis之Mapper动态代理方式
- Mybatis之Mapper动态代理方式
- Mybatis实现Mapper动态代理方式
- mybatis(6)---mapper动态代理方式
- Mybatis 动态切换数据库
- spring mybatis 动态代理
- MyBatis实现动态代理
- MyBatis---mapper动态代理
- Mybatis 的动态代理
- mybatis之动态代理
- mybatis动态代理剖析
- MyBatis--动态代理
- SpringBoot 自定义+动态切换数据源
- Java中动态代理使用
- 使用CodeWarrior出现Warning:Removed dead Code/assignment
- 架构分布式____百万级访问架构前期
- shell执行Oracle sql脚本
- tomcat启动时SessionIdGeneratorBase.createSecureRandom耗时5分钟的问题
- Android APK Decompile and Rebuild Guide
- SpringBoot+Mybatis中使用动态代理方式动态切换datasource
- 常用的JSP指令和动作
- Android代码混淆及项目发布步骤记录
- 【机器学习】Python sklearn包的使用示例以及参数调优示例
- npm 脚本(npm scripts)
- 未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
- 火星计数法(java)
- php:json中文乱码,上传流获取
- CNNIC发布第39次《中国互联网络发展状况统计报告》