spring与druid可以实现动态数据源,夸库查询,读写分离等功能。现在说一下配置:
1、需要配置多个spring数据源
spring-data.xml
<!-- 动态数据源 --> <bean id="dynamicDataSource" class="com.myproject.common.db.util.DynamicDataSource"> <!-- 通过key-value关联数据源 --> <property name="targetDataSources"> <map> <entry value-ref="dataSourceWrite" key="dataSourceWrite"></entry> <entry value-ref="dataSourceRead" key="dataSourceRead"></entry> </map> </property> <property name="defaultTargetDataSource" ref="dataSourceWrite" /> </bean> <!--mybatis与Spring整合 --> <bean id="sqlSessionFactory" name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:mybatis.xml"></property> <property name="mapperLocations" value="classpath*:mapper/*.xml" /> <property name="dataSource" ref="dynamicDataSource" /> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 数据源(DruidDataSource) --> <bean id="dataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${urlOracle}" /> <property name="username" value="${usernameOracle}" /> <property name="password" value="${passwordOracle}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="5" /> <!-- 连接池最大使用连接数量 --> <property name="maxActive" value="200" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="5" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="60000" /> <!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --> <!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> --> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- 打开removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分钟 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned" value="true" /> <!-- 监控数据库 --> <!-- <property name="filters" value="mergeStat" /> --> <property name="filters" value="stat" /> <property name="defaultAutoCommit" value="true" /> </bean> <bean id="dataSourceRead" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${urlMysql}" /> <property name="username" value="${usernameMysql}" /> <property name="password" value="${passwordMysql}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="5" /> <!-- 连接池最大使用连接数量 --> <property name="maxActive" value="200" /> <!-- 连接池最小空闲 --> <property name="minIdle" value="5" /> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="60000" /> <!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --> <!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> --> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- 打开removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分钟 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned" value="true" /> <!-- 监控数据库 --> <!-- <property name="filters" value="mergeStat" /> --> <property name="filters" value="stat" /> <property name="defaultAutoCommit" value="true" /> </bean>
2、需要写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法
public class DynamicDataSource extends AbstractRoutingDataSource { /** * * override determineCurrentLookupKey * <p> * Title: determineCurrentLookupKey * </p> * <p> * Description: 自动查找datasource * </p> * * @return */ @Override protected Object determineCurrentLookupKey() { return DBContextHolder.getDSType(); } }
3、参考spring事务管理,使用线程变量来切换数据源
public class DBContextHolder { /** * 线程threadlocal */ private static ThreadLocal<String> contextHolder = new ThreadLocal<>(); private static Logger logger = LoggerFactory .getLogger(DBContextHolder.class); public static String getDSType() { try { } catch (Exception e) { e.printStackTrace(); logger.error("get DBTYPE faild with error:[" + e.getMessage() + "]"); } String db = contextHolder.get(); if (db == null) { db =UrlConnect.getKey(ConfigHelper.getToWriteKey());// 默认是读写库 } return db; } /** * * 设置本线程的dbtype * * @param str * @see [相关类/方法](可选) * @since [产品/模块版本](可选) */ public static boolean setDSType(String str) { try { clearDBType(); if (str != null&&!str.equals("")) { contextHolder.set(str); logger.info("change thread[" + str + "] success!"); return true; } else { logger.info("change thread[" + str + "] faild!"); return false; } } catch (Exception e) { e.printStackTrace(); logger.error("change thread[" + str + "] faild!"); return false; } } /** * clearDBType * * @Title: clearDBType * @Description: 清理连接类型 */ public static void clearDSType() { contextHolder.remove(); } }
4、在dao中切换数据源
@Repository public class BaseDAO extends SqlSessionDaoSupport { @Resource private SqlSessionTemplate sqlSessionTemplate; @Resource public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) { super.setSqlSessionTemplate(sqlSessionTemplate); } public <T> PageList<T> selectPublicListPage(String countSqlID,String sqlID, PageList<T> page, Object obj) { DBContextHolder.setDbType("dataSourceRead"); //查询总数 Integer total = this.getSqlSession().selectOne(countSqlID, obj); RowBounds rowBounds=new RowBounds(page.getFirstResult(),page.getPageSize()); // 查询列表信息 List<T> list = this.getSqlSession().selectList( sqlID, obj,rowBounds); page.setTotalRecord(total!=null?total:0); page.setDataSource(list); page.setTotalPage((total + page.getPageSize() - 1) / page.getPageSize()); return page; } public int insert(String sqlID, Object paramObj) { DBContextHolder.setDbType("dataSourceWrite"); return this.getSqlSession().insert(sqlID, paramObj); } }
相关推荐
springboot+mybatis+druid+redis实现数据库读写分离和缓存
数据库是mysql,采用druid连接池。 读写分离采用插件的形式实现的,优点是不需要写源注解,不需要写分开的Mapper.xml。 如果只有主库的话,那么会创建两个地址相同的连接池,写主库,读从库。 注意:没有使用Spring...
springboot+mybatis+mysql实现读写...先在建好mysql主从数据库的配置,然后在代码中根据读写分离或强制读取master数据库中的数据 mysql数据库设置主从,参考: https://my.oschina.net/zhangmaoyuan/blog/3120556
最近项目要支持读写分离, 网上找了很多,但都是不太完整,我自己整理了下供大家参考。 我的项目使用的框架: springMvc+spring+hibernate+springJPA+maven, 数据库连接池用阿里的druid。
aop切换数据库实现读写分离。Transtraction注解事务。 MVC: 基于spring mvc注解,Rest风格Controller。Exception统一管理。 缓存和Session:注解redis缓存数据,Spring-session和redis实现分布式session同步,重启...
一个基于springboot的快速集成多数据源的启动器简介dynamic-datasource-spring-boot-starter是一个基于springboot的快速集成多数据源的启动器。其支持Jdk 1.7 +,SpringBoot 1.4.x 1.5.x 2.xx。文件| 文献资料|特性...
支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 支持数据库敏感配置信息 加密(可自定义) ENC()。 支持每个数据库独立初始化表结构schema和数据库database。 支持无数据源启动,支持懒加载...
支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 支持数据库敏感配置信息 加密(可自定义) ENC()。 支持每个数据库独立初始化表结构schema和数据库database。 支持无数据源启动,支持懒加载...
支持数据库读写分离,Feign增加服务直接的安全调用。v01版本是基础学习,主分支基于目前线上功能拆出来的功能模块,实现开箱即用。 ## 项目结构 ``` lua super-boot ├── client-config -- 项目配置文件信息...
本项目是因毕业所设计出的一个前后端分离的web应用程序,前端采用Vue框架,后端采用Spring Boot框架、数据库采用MariaDB(可自行更改为其他关系型数据库)。 项目功能: 登录、退出、注册 消息查看、消息删除 报名...
spring默认支持多数据源,基于springboot、mybatis、阿里的druid数据库连接池实现mysql主从库读写分离。
基于springboot,mybatis,druid的双数据源整合的starter介绍只需配置数据库连接信息即可实现数据库读写分离,master数据源负责写数据,slave数据源负责读数据。默认为master数据源,使用注解@ReadOnly实现数据源...
3.1.1 使用场景(`配置读写分离`) 3.1.2 读写分离 案例实操 3.1.2.1 数据库的创建 3.1.2.2创建并搭建项目 3.1.2.3 添加依赖 druid启动器的依赖 MySQL 5 的依赖 jpa的依赖 (spring-boot-starter-data-jpa) 3.1.2.4...
Spring boot + Mybatis + alibaba druid通过继承AbstractRoutingDataSource的determineCurrentLookupKey来动态切换DataSource,主从切换,读写分离。 可以直接运行,完整工程代码 + SQL脚本。
xml java系统源码 iBase4J的SpringBoot版本 ...aop切换数据库实现读写分离。Transtraction注解事务。 MVC: 基于spring mvc注解,Rest风格Controller。Exception统一管理。 调度:Spring+quartz, 可以查询、修改周
集成Druid数据源,支持原生SQL监控、防火墙监控、慢查询监控、Url监控、Spring监控等 兼容 mybatis-plus3 持久层框架,简化CRUD开发 默认添加 mybatis-typehandlers-jsr310 时间类库依赖,支持数据库时间类型到Java8...
aop切换数据库实现读写分离。Transtraction注解事务。 MVC: 基于spring mvc注解,Rest风格Controller。Exception统一管理。 调度:Spring+quartz, 可以查询、修改周期、暂停、删除、新增、立即执行,查询执行记录等...
xml java系统源码 iBase4J项目简介 iBase4J是Java语言的分布式系统架构。...aop切换数据库实现读写分离。Transtraction注解事务。 MVC: 基于spring mvc注解,Rest风格Controller。Exception统一管理。 调度:Spr
- MySQL主从复制,读写分离 - Spring Async - Spring Cache - Swagger - Spring Test - MockMvc - HTTPS - Spring DevTools - Spring Actuator - Logback+Slf4j多环境日志 - i18n - Maven Multi-Module - WebSocket ...