Spring Boot 结合 Mybatis 解决多数据源的问题

最近在研究Spring Cloud搭建微服务相关,对于一个庞大的系统,需要拆分为多个微服务,每个服务相当于一个模块,负责不同的事情,各司其职,当然,数据库之间也需要保持相对独立,这样就需要涉及到多个数据库,那么,如何使用Spring Boot配置多数据源呢?

首先,我们需要一个自定义注解,命名为:DataSource

@Retention(RetentionPolicy.RUNTIME)//将该注解定义在运行时级别@Target(ElementType.METHOD)//将该注解应用于方法上public @interface DataSource {

String value()  default  "user";}然后创建数据源的类:   DynamicDataSourceHolder
public class DynamicDataSourceHolder {

/**     *   默认数据源     *     */    public static final String DEFAULT_DATASOURCE = "user";

public static final ThreadLocal<String> holder = new ThreadLocal<String>();

public static void setDataSource(String name) {        holder.set(name);    }

public static String getDataSouce() {        return holder.get();    }

public static void clearDataSouce() {           holder.remove();        }

}

配置动态数据源的类: DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {

@Override    protected Object determineCurrentLookupKey() {        return DynamicDataSourceHolder.getDataSouce();    }

}

然后我们生成数据源,创建 MybatisConfig类 
@Configuration@PropertySource("classpath:jdbc.properties")  //引入配置文件jdbc.properties中的信息 
@MapperScan(basePackages ={"com.drive.dbuser.dao"} , sqlSessionFactoryRef = "sqlSessionFactory")   // 配置Mapper作用的位置public class MybatisConfig {

@Bean(name = "user")    @ConfigurationProperties(prefix = "user")    public DataSource dataSourceUser(){        return DataSourceBuilder.create().build();    }    //生成user数据源

@Bean(name = "drive")    @ConfigurationProperties(prefix = "drive")    public DataSource dataSourceDrive(){        return DataSourceBuilder.create().build();    }   //生成drive数据源

@Bean(name = "order")    @ConfigurationProperties(prefix = "order")    public DataSource dataSourceOrder(){        return DataSourceBuilder.create().build();    } //生成order数据源

@Bean(name = "dynamicDataSource")    public DataSource dataSource(){        DynamicDataSource dynamicDataSource = new DynamicDataSource();        // 默认数据源---User        dynamicDataSource.setDefaultTargetDataSource(dataSourceUser());        // 配置多数据源        Map<Object, Object> dataSourceMap = new HashMap(5);        dataSourceMap.put("user", dataSourceUser());        dataSourceMap.put("drive", dataSourceDrive());        dataSourceMap.put("order", dataSourceOrder());        dynamicDataSource.setTargetDataSources(dataSourceMap);        return dynamicDataSource;    }   //配置多数据源

@Bean    public SqlSessionFactory sqlSessionFactory() throws Exception {        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();        factoryBean.setDataSource(dataSource()); //        //添加XML目录        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        try {            factoryBean.setMapperLocations(resolver.getResources("classpath*:com/drive/dbuser/mapper/*.xml"));   //生效的位置            return factoryBean.getObject();        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }//创建Session工厂/*    @Bean    public SqlSessionTemplate sqlSessionTemplate() throws Exception {   //SqlSessionTemplate 是 MyBatis-Spring 的核心。 这个类负责管理 MyBatis 的 SqlSession, 调用 MyBatis 的 SQL 方法        SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory()); // 使用上面配置的Factory        return template;    }*/}

我们来看一下 jdbc.properties的配置文件的信息:
#用户服务库user.url=jdbc:mysql:***user.username=***user.password=***#打车服务库drive.url=drive.username=drive.password=#订单服务库order.url=order.username=order.password=1

user.driverClassName=com.mysql.jdbc.Driverdrive.driverClassName=com.mysql.jdbc.Driverorder.driverClassName=com.mysql.jdbc.Driver

这样我们的多数据源都配置好了,那么如何调用呢,比如说我需要先去user数据库里查数据,然后再去drive数据库里添加数据,这样怎么动态的更换数据源呢?我们可以使用Spring 中的一大核心AOP,首先我们需要在application.properties文件中开启AOP
spring.aop.auto=true#开启AOP

然后创建  DataSourceAspect类,
@Aspect@Componentpublic class DataSourceAspect  {

@Pointcut("execution(* com.drive.dbuser.dao.*.*(..))")    public void declareJointPointExpression() {    }

@Before("declareJointPointExpression()")   public void beforeSwitchDS(JoinPoint point){      //获得当前访问的class      Class<?>[]  className = point.getTarget().getClass().getInterfaces();      //获得访问的方法名      String methodName = point.getSignature().getName();      //得到方法的参数的类型      Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();      String dataSource = DynamicDataSourceHolder.DEFAULT_DATASOURCE;      try {         // 得到访问的方法对象         Method method = className[0].getMethod(methodName, argClass);         // 判断是否存在@DataSource注解         if (method.isAnnotationPresent(DataSource.class)) {            DataSource annotation = method.getAnnotation(DataSource.class);            // 取出注解中的数据源名            dataSource = annotation.value();         }      } catch (Exception e) {         e.printStackTrace();      }      // 切换数据源      DynamicDataSourceHolder.setDataSource(dataSource);   }

@After("declareJointPointExpression()")   public void afterSwitchDS(JoinPoint point){      DynamicDataSourceHolder.clearDataSouce();   }

}

这时,我们再看一下关于Dao层的内容:
@DataSource("user")List<CustomerVO>  selectCustomer(CustomerVO customerVO);
我们创建一个切面类,当我们调用Dao层之前,会首先查看在Mapper 接口上方法上的注解,并将它作为数据源,注入到DynamicDataSourceHolder中,这样,就可以实现动态切换数据源了。

最后,我们在启动类上需要加上
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) //通过禁用指定的自动化配置来避免加载不必要的自动化配置@EnableConfigurationProperties  //注解是用来开启对@ConfigurationProperties注解配置Bean的支持, 该注解告诉Spring Boot 使能支持@ConfigurationProperties:注解主要用来把properties配置文件转化为bean来使用
当然,不要忘了在pom.xml中配置所需要的依赖:
<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-web</artifactId></dependency>

<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-aop</artifactId></dependency>

<!-- Spring Boot Mybatis 依赖 --><dependency>   <groupId>org.mybatis.spring.boot</groupId>   <artifactId>mybatis-spring-boot-starter</artifactId>   <version>1.3.1</version></dependency>
<!-- MySQL 连接驱动依赖 --><dependency>   <groupId>mysql</groupId>   <artifactId>mysql-connector-java</artifactId>   <version>5.1.9</version></dependency>

<dependency>   <groupId>org.aspectj</groupId>   <artifactId>aspectjweaver</artifactId>   <version>1.7.4</version></dependency>

<dependency>   <groupId>org.aspectj</groupId>   <artifactId>aspectjrt</artifactId>   <version>1.6.12</version></dependency>

<!--log4j--><dependency>   <groupId>log4j</groupId>   <artifactId>log4j</artifactId>   <version>1.2.16</version></dependency>

好了,大功告成了,喜欢的朋友们记得关注我一下!


原文地址:https://www.cnblogs.com/hello-world-exception/p/9008437.html

时间: 2024-09-29 03:39:51

Spring Boot 结合 Mybatis 解决多数据源的问题的相关文章

Spring Boot 整合 Mybatis 实现 Druid 多数据源详解

一.多数据源的应用场景 目前,业界流行的数据操作框架是 Mybatis,那 Druid 是什么呢? Druid 是 Java 的数据库连接池组件.Druid 能够提供强大的监控和扩展功能.比如可以监控 SQL ,在监控业务可以查询慢查询 SQL 列表等.Druid 核心主要包括三部分: 1. DruidDriver 代理 Driver,能够提供基于 Filter-Chain 模式的插件体系. 2. DruidDataSource 高效可管理的数据库连接池 3. SQLParser 当业务数据量达

Spring Boot 集成 MyBatis(四)

Spring Boot 集成 MyBatis A.ORM框架是什么? 对象关系映射(Object Relational Mapping,简称 ORM)模式是一种为了解决面向对象与关系数据库存在的 互不匹配的现象技术.简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自 动持久化到关系数据库中. B.为什么需要ORM框架 当开发一个应用程序的时候(不使用 O/R Mapping),可能会写不少数据访问层的代码,用来从数据库保存. 删除.读取对象信息等.在 DAL 中写了很

第七天.spring boot 整合mybatis

一. spring boot 整合mybatis 1.整合思路: 1.1 添加依赖 mybatis 1.2 在配置文件中配置数据源信息 1.3 编写pojo mapper接口 mapeer映射文件 1.4手动配置mybatis的包扫描,在主启动类添加@MapperScan 1.5 启动springboot服务器 2.开始工程部署: 2.1:添加依赖 mybatis <!--整合springboot与mybatis的整合--> <dependencies> <dependenc

Spring Boot 集成MyBatis

Spring Boot 集成MyBatis 在集成MyBatis前,我们先配置一个druid数据源. Spring Boot 系列 Spring Boot 入门 Spring Boot 属性配置和使用 Spring Boot 集成MyBatis Spring Boot 静态资源处理 Spring Boot - 配置排序依赖技巧 Spring Boot - DevTools 介绍 Spring Boot 集成druid druid有非常多个配置选项,使用Spring Boot 的配置文件能够方便的

spring boot配置mybatis和事务管理

spring boot配置mybatis和事务管理 一.spring boot与mybatis的配置 1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spring Boot 启动父依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId>

spring boot加mybatis使用Map返回值设置

当使用spring boot加mybatis时,设置Map返回,当值为空或是null时,返回的字段不会加载到map中 在application.properties中加入下面配置,将会解决这个问题.  #当查询数据为空时字段返回为null,不加这个查询数据为空时,字段将被隐藏 mybatis.configuration.call-setters-on-nulls=true 原文地址:https://www.cnblogs.com/xueershewang/p/9055566.html

spring boot + gradle + mybatis

使用intelliJ创建 spring boot + gradle + mybatis站点 Spring boot作为快速入门是不错的选择,现在似乎没有看到大家写过spring boot + gradle + mybatis在intellij下的入门文章,碰巧做.Net的同学问到,我想我也可以写这样一篇.入门Java的人最大的问题是步骤繁琐,不知道如何开始,之前我也建议过我的一个小弟用BlueJ去学Java,可是这个东西学得他很迷茫,根本无法获得成就感,不知道能搞出什么有意思的东西,那我们就来点

企业分布式微服务云SpringCloud SpringBoot mybatis (十三)Spring Boot整合MyBatis

Spring中整合MyBatis就不多说了,最近大量使用Spring Boot,因此整理一下Spring Boot中整合MyBatis的步骤.搜了一下Spring Boot整合MyBatis的文章,方法都比较老,比较繁琐.查了一下文档,实际已经支持较为简单的整合与使用.下面就来详细介绍如何在Spring Boot中整合MyBatis,并通过注解方式实现映射. 整合MyBatis 新建Spring Boot项目,或以Chapter1为基础来操作 pom.xml中引入依赖 这里用到spring-bo

【spring boot】mybatis启动报错:Consider defining a bean of type &#39;com.newhope.interview.dao.UserMapper&#39; in your configuration.

启动报错: 2018-02-24 22:41:00.442 WARN 2952 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error c