博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
springboot动态多数据源切换
阅读量:5291 次
发布时间:2019-06-14

本文共 9298 字,大约阅读时间需要 30 分钟。

 

application-test.properties

#datasource -- mysqlmultiple.datasource.master.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=truemultiple.datasource.master.username=rootmultiple.datasource.master.password=pypuamultiple.datasource.master.driverClassName=com.mysql.jdbc.Drivermultiple.datasource.master.InitialSize=10multiple.datasource.master.MinIdle=10multiple.datasource.master.MaxActive=100multiple.datasource.slave.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=truemultiple.datasource.slave.username=rootmultiple.datasource.slave.password=pypuamultiple.datasource.slave.driverClassName=com.mysql.jdbc.Drivermultiple.datasource.slave.InitialSize=10multiple.datasource.slave.MinIdle=10multiple.datasource.slave.MaxActive=100

 

创建核心枚举类型 (多个数据源的名称)DataSourceKey

package com.pupeiyuan.core;public enum DataSourceKey {     DB_MASTER,     DB_SLAVE1,}

 

创建动态数据源DynamicRoutingDataSource,代表当前数据源

package com.pupeiyuan.core;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicRoutingDataSource extends AbstractRoutingDataSource{    @Override    protected Object determineCurrentLookupKey() {        logger.info("当前数据源:{}"+ DynamicDataSourceContextHolder.get());        return DynamicDataSourceContextHolder.get();    }}

 

创建动态数据源上下文取值类 DynamicDataSourceContextHolder.java

package com.pupeiyuan.core;import org.apache.log4j.Logger;public class DynamicDataSourceContextHolder {      private static final Logger LOG = Logger.getLogger(DynamicDataSourceContextHolder.class);      private static final ThreadLocal
currentDatesource = new ThreadLocal<>(); /** * 清除当前数据源 */ public static void clear() { currentDatesource.remove(); } /** * 获取当前使用的数据源 * * @return 当前使用数据源的ID */ public static DataSourceKey get() { return currentDatesource.get(); } /** * 设置当前使用的数据源 * * @param value 需要设置的数据源ID */ public static void set(DataSourceKey value) { currentDatesource.set(value); } /** * 设置从从库读取数据 * 采用简单生成随机数的方式切换不同的从库 */ /*public static void setSlave() { if (RandomUtils.nextInt(0, 2) > 0) { DynamicDataSourceContextHolder.set(DataSourceKey.DB_SLAVE2); } else { DynamicDataSourceContextHolder.set(DataSourceKey.DB_SLAVE1); } }*/}

 

最主要的配置 mybatisConfig

package com.pupeiyuan.config;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;import java.util.Properties;import javax.sql.DataSource;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.SqlSessionTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.annotation.Order;import org.springframework.core.io.Resource;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;import com.github.pagehelper.PageHelper;import com.pupeiyuan.core.DataSourceKey;import com.pupeiyuan.core.DynamicRoutingDataSource;import tk.mybatis.spring.annotation.MapperScan;import tk.mybatis.spring.mapper.MapperScannerConfigurer;@Configuration@MapperScan("com.pupeiyuan.mapper")public class MyBatisConfig {      @Bean        //此处的"multiple.datasource.master"需要你在application.properties中配置,详细信息看下面贴出的application.properties文件。        @ConfigurationProperties(prefix = "multiple.datasource.master")        public DataSource dbMaster() {          DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();          //配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙            try {                druidDataSource.setFilters("stat,wall,log4j");            } catch (SQLException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }                    // 通过connectProperties属性来打开mergeSql功能;慢SQL记录            druidDataSource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");            //合并多个DruidDataSource的监控数据            druidDataSource.setUseGlobalDataSourceStat(true);            return druidDataSource;        }        @Bean        @ConfigurationProperties(prefix = "multiple.datasource.slave")        public DataSource dbSlave1() {             DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();              //配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙                try {                    druidDataSource.setFilters("stat,wall,log4j");                } catch (SQLException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                            // 通过connectProperties属性来打开mergeSql功能;慢SQL记录                druidDataSource.setConnectionProperties("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");                //合并多个DruidDataSource的监控数据                druidDataSource.setUseGlobalDataSourceStat(true);                return druidDataSource;        }        /**         * 核心动态数据源         *         * @return 数据源实例         */        @Bean        public DataSource dynamicDataSource() {            DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();            dataSource.setDefaultTargetDataSource(dbMaster());            Map
dataSourceMap = new HashMap<>(4); dataSourceMap.put(DataSourceKey.DB_MASTER, dbMaster()); dataSourceMap.put(DataSourceKey.DB_SLAVE1, dbSlave1()); dataSource.setTargetDataSources(dataSourceMap); return dataSource; } @Bean public SqlSessionFactory sqlSessionFactory() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dynamicDataSource()); //此处设置为了解决找不到mapper文件的问题 //sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate() throws Exception { return new SqlSessionTemplate(sqlSessionFactory()); } /** * 事务管理 * * @return 事务管理实例 */ @Bean public PlatformTransactionManager platformTransactionManager() { return new DataSourceTransactionManager(dynamicDataSource()); } }

 

如果要配置自动切换数据源可以考虑AOP方式或者拦截器的方式进行配置,我这里采用手动切换

 

controller中手动切换

package com.pupeiyuan.controller;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.ModelAndView;import com.github.pagehelper.PageHelper;import com.pupeiyuan.bean.NhReportStatusHistory;import com.pupeiyuan.common.controller.BaseController;import com.pupeiyuan.core.DataSourceKey;import com.pupeiyuan.core.DynamicDataSourceContextHolder;import com.pupeiyuan.services.NhReportService;/** * @author pypua * @date 2018年8月30日 上午9:21:20 *  */@Controller@RequestMapping("burket")@Scope("prototype")public class BurketController extends BaseController {        //services层注入    @Autowired NhReportService nhReportService;        @RequestMapping(value = "/burketList", method = {RequestMethod.GET,RequestMethod.POST})    public ModelAndView burketList(HttpServletRequest request,            HttpServletResponse response            ) throws Exception {        System.out.println("hello,springboot");       //参数容器        Map
params = new HashMap
(); PageHelper.startPage(1, 2); DynamicDataSourceContextHolder.set(DataSourceKey.DB_SLAVE1); List
findList = nhReportService.findList(params); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("burketList"); modelAndView.addObject("list", findList); return modelAndView; } }

 

-----------------------------------------------亲测有效------------------------------------------------------

转载于:https://www.cnblogs.com/pypua/p/10081387.html

你可能感兴趣的文章
【模板】对拍程序
查看>>
微信小程序开发初体验
查看>>
dos批处理(bat)运行exe
查看>>
关键字
查看>>
Pycharm安装Markdown插件
查看>>
上传图片并预览
查看>>
哈夫曼编码_静态库
查看>>
【转】redo与undo
查看>>
C#更新程序设计
查看>>
常用Request对象获取请求信息
查看>>
解决升级系统导致的 curl: (48) An unknown option was passed in to libcurl
查看>>
Shell命令-内置命令及其它之watch、date
查看>>
Java Session 介绍;
查看>>
spoj TBATTLE 质因数分解+二分
查看>>
Django 模型层
查看>>
第8章-方法
查看>>
dedecms讲解-arc.listview.class.php分析,列表页展示
查看>>
Microsoft SQL Server Transact-SQL
查看>>
Font: a C++ class
查看>>
Extjs6 经典版 combo下拉框数据的使用及动态传参
查看>>