数据库的读写分离简单的说是把对数据库的读和写操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力。

主(master)数据库提供写操作,从(slave)数据库提供读操作,其实在很多系统中,主要是读的操作。

当主(master)数据库进行写操作时,数据要同步到从(slave)的数据库,这样才能有效保证数据库完整性。主(master)数据库同步到从(slave)数据库,从数据库一般由多台数据库组成这样才能达到减轻压力的目的。这里还要注意处理好负载均衡

使用spring的动态路由实现数据库读写分离
        Spring2.0.1以后的版本已经支持配置多数据源,并且可以在运行的时候动态加载不同的数据源。通过继承AbstractRoutingDataSource就可以实现多数据源的动态转换。目前做的项目就是需要访问2个数据源,每个数据源的表结构都是相同的,所以要求数据源的变动对于编码人员来说是透明,也就是说同样SQL语句在不同的环境下操作的数据库是不一样的。具体的流程如下:

1.建立一个获得和设置上下文的类

[java] view plaincopy
  1. package com.lvye.base.dao.impl.jdbc;
  2. /**
  3. *连接哪个数据源的环境变量
  4. */
  5. public class JdbcContextHolder {
  6. private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
  7. public static void setJdbcType(String jdbcType) {
  8. contextHolder.set(jdbcType);
  9. }
  10. public static void setSlave(){
  11. setJdbcType("slave");
  12. }
  13. public static void setMaster(){
  14. clearJdbcType();
  15. }
  16. public static String getJdbcType(){
  17. return (String) contextHolder.get();
  18. }
  19. public static void clearJdbcType() {
  20. contextHolder.remove();
  21. }
  22. }

2.建立动态数据源类,这个类必须继承AbstractRoutingDataSource

[java] view plaincopy
  1. package com.lvye.base.dao.impl.jdbc;
  2. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  3. public class DynamicDataSource extends AbstractRoutingDataSource{
  4. /*(non-Javadoc)
  5. *@see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
  6. *@author wenc
  7. */
  8. @Override
  9. protected Object determineCurrentLookupKey() {
  10. return JdbcContextHolder.getJdbcType();
  11. }
  12. }

这个类实现了determineCurrentLookupKey方法,该方法返回一个Object,一般是返回字符串。该方法中直接使用了JdbcContextHolder.getJdbcType();方法获得上下文环境并直接返回。

3.编写spring的配置文件配置数据源

[html] view plaincopy
  1. <beans>
  2. <bean id="master" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  3. <property name="driverClass">
  4. <value>com.mysql.jdbc.Driver</value>
  5. </property>
  6. <property name="jdbcUrl">
  7. <value>jdbc:mysql://192.168.18.143:3306/wenhq?useUnicode=true&characterEncoding=utf-8</value>
  8. </property>
  9. <property name="user">
  10. <value>root</value>
  11. </property>
  12. <property name="password">
  13. <value></value>
  14. </property>
  15. </bean>
  16. <bean id="slave" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  17. <property name="driverClass">
  18. <value>com.mysql.jdbc.Driver</value>
  19. </property>
  20. <property name="jdbcUrl">
  21. <value>jdbc:mysql://192.168.18.144:3306/ wenhq?useUnicode=true&characterEncoding=utf-8</value>
  22. </property>
  23. <property name="user">
  24. <value>root</value>
  25. </property>
  26. <property name="password">
  27. <value></value>
  28. </property>
  29. </bean>
  30. <bean id="mySqlDataSource" class="com.lvye.base.dao.impl.jdbc.DynamicDataSource">
  31. <property name="targetDataSources">
  32. <map>
  33. <entry key="slave" value-ref="slave"/>
  34. </map>
  35. </property>
  36. <property name="defaultTargetDataSource" ref="master"/>
  37. </bean>
  38. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  39. <property name="dataSource" ref="mySqlDataSource" />
  40. </bean>
  41. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  42. <property name="dataSource" ref="mySqlDataSource" />
  43. </bean>
  44. </beans>

在这个配置中可以看到首先配置两个真实的数据库连接,使用的msyql数据库;master和slave是按照mysql配置的主从关系的数据库,数据会自动实时同步mySqlDataSource会根据上下文选择不同的数据源。在这个配置中第一个property属性配置目标数据源,<entry key="slave" value-ref=" slave"/>中key的值必须要和JdbcContextHolder类中设置的参数值相同,如果有多个值,可以配置多个<entry>标签。第二个property属性配置默认的数据源,我们一般默认为主数据库。有些朋友喜欢使用hibernate,只需要把上面的jdbcTemplate替换为hibernate的就可以了。
4.多数据库连接配置完毕,简单测试

[java] view plaincopy
  1. public void testSave() throws Exception{
  2. jdbcContextHolder.setSlave();//设置从数据源
  3. Test test = new Test();
  4. test.setTest("www.wenhq.com.cn");
  5. mydao.save(test);//使用dao保存实体
  6. jdbcContextHolder.setMaster();//设置主数据源
  7. mydao.save(test);//使用dao保存实体到另一个库中
  8. }

5.实现读写分离,上面的测试通过了,现在就简单了我的程序是使用jdbc实现的保存数据,只是使用了c3p0的数据库连接池而已。把所有访问数据库的方法包装一下,统一调用。把执行更新的sql发送到主数据库了

[java] view plaincopy
  1. public void execute(String sql) {
  2. JdbcContextHolder.setMaster();
  3. log.debug("execute-sql:" + sql);
  4. jdbcTemplate.execute(sql);
  5. }

把查询的发送到从数据库,需要注意的是像LAST_INSERT_ID这类的查询需要特殊处理,必须发送到主数据库,建议增加专门的方法,用于获取自增长的主键。

[java] view plaincopy
  1. public List findObject(String queryString, Class clazz) {
  2. JdbcContextHolder.setSlave();
  3. log.debug("findObject-sql:" + queryString);
  4. List list = jdbcTemplate.queryForList(queryString);
  5. try {
  6. list = StringBase.convertList(list, clazz);// 将List转化为List<clazz>
  7. } catch (Exception e) {
  8. log.error("List convert List<Object> error:" + e);
  9. }
  10. AbstractRoutingDataSourcereturn list;
  11. }

转载于:https://www.cnblogs.com/moonandstar08/p/5104069.html

[转]Spring数据库读写分离相关推荐

  1. Spring - 数据库读写分离

    文章目录 Spring - 数据库读写分离 1.读写分离解决方案 1.1 应用层解决 1.2 中间件解决 2.Mysql主从配置 2.1 Mysql主从复制原理 2.2 Master主库配置 2.3 ...

  2. jedis 读写分离_Redis实现数据库读写分离

    Redis是一种NoSQL的文档数据库,通过key-value的结构存储在内存中,Redis读的速度是110000次/s,写的速度是81000次/s,性能很高,使用范围也很广. 下面用一个实例实现re ...

  3. 简单好用!利用Spring AOP技术10分钟实现一个数据库读写分离方案

    前言 最近我们的APP在线用户越来越多,接口的响应速度也是越来越慢,经过运维排查发现是由于并发查询太多导致的数据库压力比较大,架构师经过调研给出了数据库读写分离的解决方案,为了快速解决问题,我们最终采 ...

  4. java spring mysql配置_java相关:mysql+spring+mybatis实现数据库读写分离的代码配置

    java相关:mysql+spring+mybatis实现数据库读写分离的代码配置 发布于 2020-4-4| 复制链接 分享一篇关于关于mysql+spring+mybatis实现数据库读写分离的代 ...

  5. Spring 实现数据库读写分离

    Spring 实现数据库读写分离 现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Master库负责数据更新和实时数据查询,Slave库当然 ...

  6. 跟我学Springboot开发后端管理系统5:数据库读写分离

    在Matrix-web后台管理系统中,使用到了数据库的读写分离技术.采用的开源的Sharding-JDBC作为数据库读写分离的框架.Matrix-Web后台数据库这一块采用的技术栈如下: 使用Myba ...

  7. 解决数据库读写分离(转)

    如何配置mysql数据库的主从? 单机配置mysql主从:http://my.oschina.net/god/blog/496 常见的解决数据库读写分离有两种方案 1.应用层 http://neore ...

  8. PG SQL数据库读写分离的思路

    PGSQL可以设置一台主多个SLAVE,这样我们需要一个办法能在程序里做到读写分离,查询了互联网,找到了下面的解决思路,请周枫在后继开发中测试下面的思路方案: 在应用层通过spring特性解决数据库读 ...

  9. mybatis获取mysql源数据类型_spring集成mybatis实现mysql数据库读写分离

    前言 在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈.幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库的数据更新同步到另一台服务器上. ...

最新文章

  1. 0基础培训java必须掌握的一些知识点
  2. 【 C 】assert.h 简明介绍
  3. 算法------长度最小的子数组
  4. IoC(Inversion of Control,控制反转)模式
  5. JavaWeb:CSS层叠样式表
  6. 请简述一下线程的sleep()方法和yield()方法的区别?
  7. php 上传文件 例子,php上传文件实例
  8. 填坑-十万个为什么?(18)
  9. KETTLE6.0版本体验小结
  10. 简单解决新浪博客“您短时间发表文章过多,请稍后再试”的问题
  11. LinkedIn第三方登录(JavaScript SDK)
  12. 【控制】PID和LQR
  13. 乱斗西游小白龙技能预设释放顺序
  14. springboot项目linux系统设置开机启动项(亲测可用)
  15. base64上传文件,后端接受处理(四)
  16. Zabbix-3.0.X 监测服务器硬盘IO状态
  17. adams 绳索仿真
  18. 多线程练习:模拟多人爬山
  19. rdkit安装指南-常见问题解决(rdkit找不到包、下载时加载0%)
  20. ActiveSync与设备连接

热门文章

  1. skyline point解析
  2. python将学生信息保存到文件中_Python statsmodels OLS:如何将学习的模型保存到文件中...
  3. Pytorch开发环境安装(Windows版本)
  4. leetcode —— 207. 课程表
  5. leetcode —— 133. 克隆图
  6. leetcode - K 站中转内最便宜的航班
  7. 高效的Java集合框架GNU Trove的使用
  8. 网络爬虫之java基础(Ⅰ)
  9. 深拷贝与浅拷贝的区别
  10. 最大子段和问题——详解(C++)