• Spring学习总结(18)——Spring整合Mysql数据库一主多从、多主多从配置


    一、新建jdbc.properties配置文件

    1. master.jdbc.driverClassName=com.mysql.jdbc.Driver
    2. master.jdbc.url=jdbc:mysql://127.0.0.1:3306/springdemo?useUnicode=true&characterEncoding=UTF-8
    3. master.jdbc.username=root
    4. master.jdbc.password=123456
    5. slave.jdbc.driverClassName=com.mysql.jdbc.Driver
    6. slave.jdbc.url=jdbc:mysql://127.0.0.1:3306/springdemo?useUnicode=true&characterEncoding=UTF-8
    7. slave.jdbc.username=read
    8. slave.jdbc.password=123456

    配置文件的作用大家都清楚了,是因为我们可以在applicationContext.xml文件中以${master.jdbc.url}的形式读取内容,配置文件一般在/src/目录下。

    二、配置applicationContext.xml

    1. <!-- 将多个配置文件读取到容器中,交给Spring管理 -->
    2. <bean id="propertyConfigurer"
    3. class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    4. <property name="locations">
    5. <list>
    6. <value>classpath:global.properties</value>
    7. <value>classpath:jdbc.properties</value>
    8. </list>
    9. </property>
    10. </bean>
    11. <!--master 配置数据源 -->
    12. <bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource"
    13. init-method="init" destroy-method="close">
    14. <property name="driverClassName">
    15. <value>${master.jdbc.driverClassName}</value>
    16. </property>
    17. <property name="url">
    18. <value>${master.jdbc.url}</value>
    19. </property>
    20. <property name="username">
    21. <value>${master.jdbc.username}</value>
    22. </property>
    23. <property name="password">
    24. <value>${master.jdbc.password}</value>
    25. </property>
    26. ...
    27. </bean>
    28. <!--slave 配置数据源 -->
    29. <bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource"
    30. init-method="init" destroy-method="close">
    31. <property name="driverClassName">
    32. <value>${slave.jdbc.driverClassName}</value>
    33. </property>
    34. <property name="url">
    35. <value>${slave.jdbc.url}</value>
    36. </property>
    37. <property name="username">
    38. <value>${slave.jdbc.username}</value>
    39. </property>
    40. <property name="password">
    41. <value>${slave.jdbc.password}</value>
    42. </property>
    43. ...
    44. </bean>
    45. <bean id="dataSource" class="cn.mayongfa.service.imp.DynamicDataSource">
    46. <property name="targetDataSources">
    47. <map>
    48. <entry key="slave" value-ref="slaveDataSource" />
    49. </map>
    50. </property>
    51. <property name="defaultTargetDataSource" ref="masterDataSource" />
    52. </bean>
    53. <!-- 配置Jdbc模板 -->
    54. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    55. <property name="dataSource" ref="dataSource"></property>
    56. </bean>
    57. <!-- 配置事务管理器 -->
    58. <bean id="transactionManager"
    59. class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    60. p:dataSource-ref="dataSource" />
    61. <!-- 数据源切换类 -->
    62. <bean id="dataSourceChoose" class="cn.mayongfa.interceptor.DataSourceChoose" />
    63. <!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
    64. ...

    上面配置我省略了 druid 数据连接池的一些配置和 service 层事务处理,文件并不完整,具体文件示例见GitHub:https://github.com/mafly/SpringDemo/blob/master/WebContent/WEB-INF/applicationContext.xml

    如何使用阿?

    我直接贴一个具体的 Service 层代码你就完全懂了。

    1. public interface UserBasisService {
    2. /**
    3. * 保存
    4. * @param entity
    5. * @return
    6. */
    7. @DataSource
    8. public long Save(UserBasis entity);
    9. /**
    10. * 删除
    11. * @param ID
    12. * @return
    13. */
    14. @DataSource
    15. public Boolean Delete(long ID);
    16. /**
    17. * 获取信息
    18. * @param ID
    19. * @return
    20. */
    21. @DataSource(DataSourceType.Slave)
    22. public UserBasis getEntity(long ID);
    23. /**
    24. * 根据条件获取数据条数
    25. * @return
    26. */
    27. @DataSource(DataSourceType.Slave)
    28. public int getListCount(Map<String, Object> whereMap);
    29. /**
    30. * 获取所有
    31. * @return
    32. */
    33. @DataSource(DataSourceType.Slave)
    34. public List<UserBasis> getList();
    35. }

    就是直接打标签的形式切换就可以了,这里需要注意的有两点,也是我们曾经踩过的坑:
    1.注意事务是在何处!就是说,要在一个事务开始之前做数据源的切换。
    2.不要又想写又想读!还是在一个事务内不要有读的方法又有写的方法。

    到这里读写分离和主从动态切换数据源的配置以及使用就完整了。接下来思考:我们是不是有时候项目都是要一主多从、多主多从?

    一主多从、多主多从

    一主多从的架构很多人都在使用,美其名是减小读数据的压力,我还是保留上一篇文章的看法,可能数据安全是最大的作用,再有就是你有数据报表和数据统计系统,使用一主多从架构可以避免生产服务器的访问压力过大。
    配置一主多从架构其实根据我们上面的设计就很简单了,只需要在applicationContext.xml文件中配置多个从库数据源就可以,然后当你读取从库时,可根据你现有的从库数来进行一些负载均衡算法的切换,我这里就不再演示了。

    多主多从是什么鬼?首先我需要说明的是多主多从这里并不是指的同一个业务数据库,是指不同的业务数据库,就是大家所说的「分库分表」中的分库,就是说我们一个项目中分出了不同的业务数据库,然后这些不同的数据库也可以有多个从库,可不是一个业务数据库有多个主库、多个从库,据我所知, MySql 的复制也是不建议这么做的。
    了解清楚概念后,我们目标就清晰了,其实根据我们的数据源切换架构,再接着配置多个数据源就可以了。其实也是这么简单的意思,比如:项目中有个金币系统,用户完成我们期望的操作就会给他相应的金币,他可以用金币兑换我们商城里的物品。这时候,其实我们就应该有个金币库了,不要再去和业务共用一个数据库,所以,这时候就会用到我们「多主多从」的架构了。

  • 相关阅读:
    RocketMq总结(六) -- 顺序消息
    RocketMq总结(五) -- 消息队列负载均衡和再分配
    RocketMq总结(三) -- 消费者启动 MQClientInstance
    归并排序
    CMS垃圾收集器总结
    桶排序
    快速排序
    ThreadLocal的妙用
    NC_41 找最小的k个数
    RocketMq一条消息存储结构
  • 原文地址:https://www.cnblogs.com/zhanghaiyang/p/7212882.html
Copyright © 2020-2023  润新知