`
longgangbai
  • 浏览: 7348793 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【转】spring 数据库读写分离

阅读更多

什么是数据库的读写分离

数据库的读写分离简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻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. }  
分享到:
评论

相关推荐

    springaop多数据库读写分离

    要实现Spring AOP的多数据库读写分离,我们需要以下步骤: 1. **配置数据源**:首先,我们需要配置多个数据源,一个作为主库(处理写操作),另一个或多个作为从库(处理读操作)。这可以通过Spring的`...

    在应用层透过spring解决数据库读写分离

    在应用层透过Spring解决数据库读写分离 数据库读写分离是指将数据库的读取和写入操作分开处理,以提高数据库的性能和可用性。在应用层解决数据库读写分离可以通过Spring框架来实现,本文将介绍如何使用Spring解决...

    Spring实现数据库读写分离代码

    通过以上分析,我们可以看出,Spring、Spring MVC、MyBatis和MySQL的组合,为实现数据库读写分离提供了一种高效且灵活的解决方案。理解并掌握这些知识点,对于提升系统的稳定性和性能具有重要的意义。

    使用Spring实现读写分离(MySQL实现主从复制)

    本篇文档将详细探讨如何利用Spring框架实现数据库的读写分离,并结合MySQL的主从复制机制,确保系统的稳定运行和高效响应。 ### 背景分析 在实际应用中,许多系统面临着数据读取压力远大于写入压力的情况,这导致...

    Spring实现数据库读写分离

    通过以上步骤和策略,我们可以利用Spring、Spring MVC和MyBatis构建一个高效、稳定的数据库读写分离系统,提升系统的整体性能和可用性。在实际项目中,还需要根据具体需求和业务场景进行相应的调整和优化。

    springboot+mybatis+druid+redis实现数据库读写分离和缓存

    在现代Web应用开发中,数据库读写分离和缓存技术是提高系统性能和可扩展性的关键策略。本项目采用SpringBoot、MyBatis、Druid和Redis这四个核心技术来实现这一目标。以下将详细讲解这些组件如何协同工作,以及它们...

    springboot实现mysql的读写分离的案例源码

    读写分离就是对于一条SQL该选择哪一个数据库去执行,至于谁来做选择数据库这件事,有两个,要么使用中间件帮我们做,要么程序自己做。一般来说,读写分离有两种实现方式。第一种是依靠中间件MyCat,也就是说应用程序...

    在应用层通过spring特性解决数据库读写分离代码

    下面将详细探讨如何利用Spring的特性来解决数据库读写分离的问题。 首先,我们需要理解读写分离的基本概念。读写分离是将数据库的读操作和写操作分配到不同的服务器上,通常主数据库负责写操作,而从数据库处理读...

    spring+springmvc+mybatis的整合以及数据库读写分离的测试

    本项目将这些框架进行了整合,并进行了数据库读写分离的配置,以提高系统的稳定性和性能。 首先,Spring框架作为基础,提供了强大的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented ...

    spring mysql 读写分离

    Spring框架提供了对MySQL数据库读写分离的良好支持,使得开发者能够轻松地在应用中实现这一功能。 **1. 什么是读写分离** 读写分离是指在数据库系统中,将读操作和写操作分配到不同的服务器上执行,读操作通常发生...

    数据库读写分离demo

    数据库读写分离是一种常见的优化策略,它通过将数据的读取操作和写入操作分散到不同的数据库服务器上,以提高系统的并发处理能力和响应速度。在大型应用系统中,由于读操作通常远多于写操作,读写分离可以显著降低主...

    spring+springmvc+mybatis+maven+mysql数据库读写分离

    在构建大型分布式系统时,数据库读写分离是一个重要的优化策略,它可以提高系统的可扩展性和性能。本项目结合了Spring、SpringMVC、MyBatis和Maven等技术,与MySQL数据库一起实现读写分离,以提升应用的处理能力。...

    数据库读写分离(aop方式完整实现)

    最近项目要支持读写分离, 网上找了很多,但都是不太完整,我自己整理了下供大家参考。 我的项目使用的框架: springMvc+spring+hibernate+springJPA+maven, 数据库连接池用阿里的druid。

    基于JAVA springboot的SPI的数据库读写分离starter+源码+项目文档(毕业设计&课程设计&项目开发)

    基于JAVA springboot的SPI的数据库读写分离starter+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于JAVA springboot的SPI的...

    AOP动态实现MYSQL数据库读写分离

    在现代的高并发、大数据量的应用系统中,数据库的读写分离是一种常见的优化策略,它能够有效提升系统的处理能力和响应速度。本示例通过Java的面向切面编程(AOP)技术来实现实现MySQL数据库的读写分离,旨在帮助...

    基于SpringAOP的数据库读写分离的实现

    基于SpringAOP的数据库读写分离的实现,可以点击查看我的博客,有详细讲解http://blog.csdn.net/qism007

    JAVA数据库读写分离项目源码(MYSQL)

    在Java开发领域,数据库读写分离是一种常见的优化策略,它能显著提高系统性能,尤其是在高并发环境下。本项目源码是基于MySQL数据库实现的,利用SSM(Spring、SpringMVC、MyBatis)框架进行开发,旨在帮助开发者快速...

    读写分离测试sql

    Spring实现数据库读写分离/spring事务配置解释(Annotation/Spring AOP/Reflection)的辅助sql

    Mysql主从集群搭建方法,以及基于spring boot注解式数据库读写分离代码示例.zip

    Spring Boot是流行的Java开发框架,提供了便捷的方式来配置和使用数据库,包括实现数据库读写分离。 1. **MySQL主从复制原理**: 主从复制的核心是binlog(二进制日志),主节点的所有更改操作都会记录在binlog中...

Global site tag (gtag.js) - Google Analytics