第八章 springboot + mybatis + 多数据源3(使用切面AOP)
引入 aop包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
1.新建注解 DS
package com.example.abstractroutingdatasource.config; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 在方法上使用,用于指定使用哪个数据源 * * @version v.0.1 */ @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface DS { String value(); }
2.新建AOP DataSourceAspect
package com.example.abstractroutingdatasource.config; import com.sun.corba.se.impl.orb.DataCollectorBase; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Aspect @Order(-10)//保证该AOP在@Transactional之前执行 @Component public class DataSourceAspect { /* * @Before("@annotation(ds)") * 的意思是: * @Before:在方法执行之前进行执行: * @annotation(targetDataSource): * 会拦截注解targetDataSource的方法,否则不拦截; */ // @Before("execution(* com.example.*.dao..*.*(..))") @Before("@annotation(ds)") public void changeDataSource(JoinPoint point,DS ds) throws Throwable { //获取当前的指定的数据源; String dsId =ds.value(); //如果不在我们注入的所有的数据源范围之内,那么输出警告信息,系统自动使用默认的数据源。 DatabaseContextHolder.setDatabaseType(dsId); } @After("@annotation(ds)") public void restoreDataSource(JoinPoint point, DS ds) { System.out.println("Revert DataSource : {} > {}"+ds.value()+point.getSignature()); //方法执行完毕之后,销毁当前数据源信息,进行垃圾回收。 DatabaseContextHolder.ClearDataBaseType(); } }
3.在dao 上加注解
package com.example.abstractroutingdatasource.dao; import com.example.abstractroutingdatasource.config.DS; import com.example.abstractroutingdatasource.config.DatabaseContextHolder; import com.example.abstractroutingdatasource.entity.UcUser; import com.example.abstractroutingdatasource.mapper.UcUserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.net.UnknownHostException; @Repository public class UcUserDao { @Autowired private UcUserMapper ucUserMapper; @DS(value="1") public UcUser selectOne(String id,String ds ){ // DatabaseContextHolder.setDatabaseType(ds); //手动设置库 return ucUserMapper.getUser(id); } @DS(value="2") public UcUser selectOne2(String id,String ds ){ // DatabaseContextHolder.setDatabaseType(ds); //手动设置库 return ucUserMapper.getUser(id); } }
4.完成,启动应用访问页面 数据源会自动切换
demo 链接: https://pan.baidu.com/s/1rpC7lMxF_ENW_zLr7MGlBQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2012-05-31 分析器错误消息: Inherits="DtCms.Web.Aspx.tt.txm"不扩展类“System.Web.UI.Page”,因此此处不允许。