之前有写过在linux上搭建多个mysql实例,然后又写了一篇多个mysql之间如何配置主从,现在终于到了如何使用的时候了,这篇文章就说明了,如何在程序中,而且是在通常的项目结构(基于Spring构建的项目中)中如何使用。
一、说说原理
简单的不能再简单了,配置多个datasource ,不同的方法使用不同的datasource。比如说,来自主库的datasource1,来自从库的datasource2 ,方法method1有数据更改操作(insert, update,delete), 使用datasource1, 方法method2有查询操作(select),使用datasource2。
为什么这么设计呢,因为对于一个项目来时候,绝大部分的数据库操作是查询,而不是更改,而且更改和查询的机制和方式不一样,更改涉及到的是对单表的修改,所的机制,事务的处理,而查询更多的是索引,主键的关联方面。
如果对mysql了解多一点的可能会有新的问题,如果我把主库的存储引擎弄成InnoDB来支持事务,从库用不支持事务的存储引擎来加快查询速度,这不是很好吗?的确很不错,但是有一个问题,如果主库挂了之后,从库需要立即来担任主库的责任的时候,这时候从库不支持事务,部分操作可能会引起问题。所以要视情况来说了,也可以通过多个从库来弥补一下这个问题。
二、Spring如何使用主从
在Spring使用主从主要利用了切面(AOP)和AbstractRoutingDataSource这个抽象类, 流程是这样的,在某一个或者某一类型的类的上加一个切面,当此类方法被调用时,会进入切面,根据方法之前设置的类型,被指向某个切面的datasource实例,这样,当调用mapper的时候就会使用这个datasource来操作数据库了。
做PPT的时候画了个草图,大家凑合看吧。
代码如下
有自定义注解如下
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = ElementType.METHOD) public @interface DataSource { String value(); }实现类方法如下
@Override @DataSource(value="slave") public List<Map<String, Object>> getMaterials(String name, String code, String type, String state) { try { List<Map<String, Object>> materials = this.materialMapper.getMaterials(null, name, code, type, state); return materials; } catch (Exception e) { e.printStackTrace(); } return null; }Spring 相关配置如下
<bean id="basic" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" abstract="true"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- Connection Pooling Info --> <property name="maxTotal" value="${jdbc.pool.maxActive}" /> <property name="maxIdle" value="${jdbc.pool.maxIdle}" /> <property name="minIdle" value="0" /> <property name="defaultAutoCommit" value="false" /> </bean> <!-- 从库 --> <bean id="slaveDataSource" parent="basic"> <property name="url" value="${jdbc.url.second}" /> </bean> <!-- 主库 --> <bean id='masterDataSource' parent="basic"> <property name="url" value="${jdbc.url.main}" /> </bean> <!-- 数据源 --> <bean id="dataSource" class="com.fantong.common.datasource.DataSourceSwitcher"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="master" value-ref="masterDataSource" /> <entry key="slave" value-ref="slaveDataSource" /> </map> </property> <property name="defaultTargetDataSource" ref="masterDataSource"> </property> </bean> <!-- 配置切面 用于分库 --> <aop:aspectj-autoproxy /> <bean id="dataSourceAspect" class="com.fantong.common.datasource.DataSourceAspect" /> <aop:config> <aop:aspect id="c" ref="dataSourceAspect"> <aop:pointcut id="tx" expression="execution(* *..service.impl.*.*(..))" /> <aop:before pointcut-ref="tx" method="before" /> </aop:aspect> </aop:config>相关自定义类
DataSourceAspect
import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; public class DataSourceAspect { public void before(JoinPoint point) { Object target = point.getTarget(); String method = point.getSignature().getName(); Class<? extends Object> classz = target.getClass(); Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes(); try { Method m = classz.getMethod(method, parameterTypes); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource data = m.getAnnotation(DataSource.class); DataSourceSwitcherToken.putToken(data.value()); System.out.println(data.value()); } } catch (Exception e) { e.printStackTrace(); } } }DataSourceSwitcher
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DataSourceSwitcher extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceSwitcherToken.getToken(); } }DataSourceSwitcherToken
public class DataSourceSwitcherToken { public static final ThreadLocal<String> token = new ThreadLocal<String>(); public static void putToken(String name) { token.set(name); } public static String getToken() { return token.get(); } public static void relaxToken() { token.remove(); } }
相关推荐
本篇文章将详细讲解如何在SpringBoot项目中结合MybatisPlus实现多数据源配置,以及主从库的读写分离。 首先,我们要理解什么是SpringBoot和MybatisPlus。SpringBoot是由Pivotal团队提供的全新框架,其目的是简化...
springboot+mybatis+mysql实现读写...先在建好mysql主从数据库的配置,然后在代码中根据读写分离或强制读取master数据库中的数据 mysql数据库设置主从,参考: https://my.oschina.net/zhangmaoyuan/blog/3120556
Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换
本项目基于SpringBoot 2.0框架和MyBatis持久层技术,实现了主从数据库双数据源的配置,确保在高并发环境下既能保证数据的一致性,又能提升读取效率。 SpringBoot 2.0是Spring框架的一个轻量级版本,它简化了Spring...
通过上述步骤,我们可以实现基于SpringMVC、MyBatis和Druid的读写分离,以及Windows上的MySQL主从复制。这将大大提高系统的可伸缩性和可用性,降低单点故障的风险。在实际项目中,还可以根据业务需求进一步优化,...
* 首页及其他页面因为读多写少,利用Mysql主从复制实现读写分离,写入在主Mysql下进行,读取在从Mysql进行 * 关于数据的不一致性,可以在写入的时候先写入缓存,读取的时候也先在缓存中读取,这样就可以避免数据的不...
Spring Boot 配置 MySQL 数据库连接、Hikari 连接池和 MyBatis 的简单配置方法 Spring Boot 是一个基于 Java 的框架,用于快速构建生产级别的应用程序。作为一个现代化的框架,Spring Boot 提供了许多便捷的配置...
在SpringBoot项目中集成MyBatis和MySQL,通常会利用MyBatis-Spring Boot Starter简化配置,通过Spring的自动配置机制,将MyBatis与Spring Boot无缝连接。在配置文件中设置数据源,并在Mapper接口上使用注解或XML文件...
首先,需要在pom文件中添加相关依赖,包括 Jackson 库、Spring Boot JDBC、MySQL 连接器、Druid 数据源、MyBatis、tk.mybatis Mapper、PageHelper 分页插件等。这些依赖项是实现主从(多数据源)分离方案的必要条件...
本项目结合了Spring、SpringMVC、MyBatis和Maven等技术,与MySQL数据库一起实现读写分离,以提升应用的处理能力。下面将详细解释这些技术及其在读写分离中的作用。 首先,Spring是一个开源的Java平台,它提供了全面...
2. **MySQL主从同步**: - **复制配置**:设置主库和从库的复制关系,主库的数据更改会自动同步到从库。 - **binlog日志**:主库通过binlog记录所有更改操作,从库通过I/O线程读取并应用这些日志。 - **主从切换*...
在企业级应用开发中,经常需要访问和操作多个数据库,这种需求促使了多数据源配置与管理在Spring框架和MyBatis持久层框架中的重要性。下面对这个主题的知识点进行详细说明。 1. **多数据源场景介绍** 在处理多数据...
至此,我们已经完成了 Spring 和 MyBatis 的多数据源动态切换配置。在实际应用中,可以根据业务场景灵活地切换数据源,实现读写分离、负载均衡等高级功能。需要注意的是,数据源切换应在事务边界内完成,以确保数据...
本配置示例将详细介绍如何在Spring Boot中整合MyBatis与Oracle数据库,并配置两个不同的数据源。 首先,我们需要理解数据源(DataSource)的概念。数据源是Java应用程序与数据库之间的桥梁,它负责管理数据库连接,...
1. **SpringBoot框架**:SpringBoot简化了Spring应用的初始搭建以及开发过程,它集成了大量常用的第三方库配置,如JPA、Thymeleaf、FreeMarker等,让你可以快速地创建一个独立的、生产级别的基于Spring的应用。...
在Java开发中,MyBatis、MySQL和Log4j是三个非常重要的库,它们各自扮演着不同的角色,为开发者提供便利。以下是对这三个组件的详细解释: 1. MyBatis: MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程...
Java面试题合集是针对Java开发人员的一份全面的复习资料,涵盖了多个核心技术和框架,包括JavaEE、Spring、SpringMVC、SpringBoot、MyBatis以及MySQL等。这些技术在现代企业级应用开发中占据着重要地位,因此对它们...
通过配置主从数据源,当应用需要执行插入、更新或删除操作时,会自动路由到主库,而查询操作则会指向从库,这样可以显著提高系统的并发处理能力。德鲁伊还提供了丰富的监控统计功能,帮助开发者实时了解数据库访问...
《构建基于SpringMVC+Mybatis+MySQL的云笔记系统详解》 在现代Web开发领域,SpringMVC、Mybatis和MySQL是常见的技术栈,它们共同构建了一个高效、灵活且可扩展的应用架构。本篇文章将深入探讨如何使用这三大核心...