springboot2+druid+mybatis多数据源配置(代码片段)

song27 song27     2022-12-16     520

关键词:

在大数据高并发的应用场景下,为了更快的响应用户请求,读写分离是比较常见的应对方案。读写分离会使用多数据源的使用。下面记录如何搭建SpringBoot2 + Druid + Mybatis  多数据源配置以及在使用过程遇到的问题。

一、先从pom.xml入手(使用springboot 2的版本)

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>

inject是java依赖注入标准。spring默认支持识别。spring自带的@Autowired的缺省情况等价于JSR-330的@Inject注解;@Qualifier的缺省的根据Bean名字注入情况等价于JSR-330的@Named注解。

二、添加读取DB的Mapper

@Mapper
public interface AssetMapper

@Select("select * from Asset where account = #account")
Asset queryName(String account);

此处使用mybatis的注解功能,因此可以少省去*.xml等配置文件。

三、添加多数据源的配置参数

spring.datasource.druid.write.url=jdbc:mysql://192.168.0.110:3306/master?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.druid.write.username=root
spring.datasource.druid.write.password=123456
spring.datasource.druid.write.driver-class-name=com.mysql.cj.jdbc.Driver
#
spring.datasource.druid.read.url=jdbc:mysql://192.168.0.110:3306/slave1?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.druid.read.username=root
spring.datasource.druid.read.password=123456
spring.datasource.druid.read.driver-class-name=com.mysql.cj.jdbc.Driver

新版本mysql的url后面必需要添加serverTimezone=。 不然会报以下异常:
2019-06-05 18:47:24.058 ERROR 17804 --- [-Create-6910184] com.alibaba.druid.pool.DruidDataSource   : create connection SQLException, url: jdbc:mysql://localhost:3306/master, errorCode 0, state 01S00

java.sql.SQLException: The server time zone value ‘?й???????‘ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
   

四、配置数据源

@Configuration
public class DataSourceConfig

@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.write")
@Primary
public DataSource masterDataSource()
return DruidDataSourceBuilder.create().build();


@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.read")
public DataSource slaveDataSource()
return DruidDataSourceBuilder.create().build();


@Inject
@Named("masterDataSource")
private DataSource masterDataSource;

@Inject
@Named("slaveDataSource")
private DataSource slaveDataSource;

/**
* 根据数据源创建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
return sessionFactory.getObject();


SqlSessionFactory必需要重新创建,若不创建会报循环调用异常

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘masterDataSource‘: Requested bean is currently in creation: Is there an unresolvable circular reference?

因为SqlSessionFactory还是走默认创建的方式 。

上下文中如何得知使用那个数据源,可使用ThreadLocal来处理。

五、数据源路由


public class DataSourceContextRouting implements AutoCloseable

static final ThreadLocal<String> dataSourceKeyThreadLocal = new ThreadLocal<>();

public String getDataSourceName()
String key = dataSourceKeyThreadLocal.get();
return StringUtils.isBlank(key) ?"masterDataSource":key;


public DataSourceContextRouting(String key)
dataSourceKeyThreadLocal.set(key);


@Override
public void close() throws Exception
dataSourceKeyThreadLocal.remove();

spring的提供动态源实现功能。只需要继承AbstractRoutingDataSource,并重写protected Object determineCurrentLookupKey()

public class DynamicDataSource extends AbstractRoutingDataSource 
@Override
protected Object determineCurrentLookupKey()
return DataSourceContextRouting.getDataSourceName();

 //此为核心代码

@Bean

public DynamicDataSource dataSource() 
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("masterDataSource", masterDataSource);
targetDataSources.put("slaveDataSource", slaveDataSource);

DynamicDataSource dataSource = new DynamicDataSource();
//设置数据源映射
dataSource.setTargetDataSources(targetDataSources);
//设置默认数据源,当无法映射到数据源时会使用默认数据源
dataSource.setDefaultTargetDataSource(slaveDataSource);
dataSource.afterPropertiesSet();
return dataSource;

 六、controller路由切换

 @RequestMapping("master")
public String master(String account)
String key = "masterDataSource";
new DataSourceContextRouting(key);
//TODO .....

@RequestMapping("slave")
public String slave(String account)
String key = "slaveDataSource";
new DataSourceContextRouting(key);
      //TODO......

 到此为止,整个多数据源配置完成了。

但这种对代码侵入比较多,可以使用注解的方式来处理。先定义注解标识

@Target(ElementType.METHOD, ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource
String value();

 使用注解那需要对此进行解析切入,因此就需要用上spring AOP的功能。

 首先添加maven依赖

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

 然后添加对其解析Aspect

@Aspect
@Named
public class DataSourceRoutingAspect
@Around("@annotation(targetDataSource)")
public Object routingWithDataSource(ProceedingJoinPoint joinPoint, TargetDataSource targetDataSource) throws Throwable
String key = targetDataSource.value();
try (DataSourceContextRouting ctx = new DataSourceContextRouting(key))
return joinPoint.proceed();


 @RequestMapping("master")
@TargetDataSource("masterDataSource")
public String master(String account)
TODO:.....

@RequestMapping("slave")
@TargetDataSource("slaveDataSource")
public String slave(String account)
TODO:.....

 

springboot2.0.4整合springdatajpa和druid,双数据源

最近Team开始尝试使用SpringBoot+SpringDataJPA作为数据层的解决方案,在网上逛了几圈之后发现大家并不待见JPA,理由是(1)MyBatis简单直观够用,(2)以Hibernate为底层的SpringDataJPA复杂且性能一般。但是当我们来到SpringBoot的世界后发现,... 查看详情

springboot2.5.5配置mybatis(代码片段)

【README】1.本文记录了springboot2.5.5配置mybatis的步骤;2.配置mybatis分为注解和配置两种方式;3.引入mybatis,包括了创建springbt项目;druid数据源配置;数据库表与javabean;mybatis配置与sql映射;用户请求contro... 查看详情

学习整合springboot2.0和mybatis,实现基本的crud

前言:本文是在自己整合springboot2.0和mybatis时的过程和踩得坑。先附上github地址:https://github.com/yclxt/springboot-mybatis.git环境/版本:工具:IntellijIDEA2018.3JDK:1.8Springboot:2.0.4.RELEASEMybatis:1.3.2由于本人是初学者,对druid和handlePage不太熟 查看详情

springboot2.x+maven+mybatis+shiro+redis

...的一哥们的springboot1.X整合shiro和redis的demo,我用的是springboot2.X,改了下,添加了druid和swagger2,部分,公司屏蔽git,只能上传csdn备份。那位哥们的原文找不到了,sorry。部署resource/sql/shiro.sql&# 查看详情

springboot2.1.1.release集成druid

SpringBoot2.1.1.RELEASE集成Druid详情:http://www.qchcloud.cn/system/article/show/68配置依赖:mysqlmysql-connector-javacom.alibabadruid1.1.4配置applicaton.propertiesspring.datasource.driverClassName=com.mysql.cj.j 查看详情

springboot2.x+maven+mybatis+shiro+redis

...的一哥们的springboot1.X整合shiro和redis的demo,我用的是springboot2.X,改了下,添加了druid和swagger2,部分,公司屏蔽git,只能上传csdn备份。那位哥们的原文找不到了,sorry。部署resource/sql/shiro.sql;修改applicati... 查看详情

springboot2-11web-druid数据源

2、使用Druid数据源1、druid官方github地址https://github.com/alibaba/druid整合第三方技术的两种方式自定义找starter2、自定义方式1、创建数据源2、StatViewServletStatViewServlet的用途包括:提供监控信息展示的html页面提供监控信息的JSONAPI3... 查看详情

springboot2——数据访问的集成&单元测试(junit5)(代码片段)

SpringBoot2——数据访问的集成&单元测试(JUnit5)一、数据访问1.1数据库场景的自动配置(HikariDataSource)1.2整合druid数据源1.2.1自定义druid数据源1.2.2使用官方starter方式1.3整合MyBatis操作(重点)1.3.1整合过... 查看详情

springboot2基于springboot实现ssmp整合(代码片段)

前言​    重头戏来了,SpringBoot之所以好用,就是它能方便快捷的整合其他技术,本文讲解一些技术的整合方式,通过这本文的学习,感受SpringBoot到底有多酷炫。本文学习如下技术的整合方式整合JUnit整... 查看详情

springboot2.5.5配置druid数据源1.2.8与jdbc(代码片段)

【README】本文记录了springboot配置druid数据源的步骤;【1】新建springboot项目并配置druid步骤1,新建springbt项目 步骤2,选择springweb,jdbc,mysql驱动依赖;步骤3,添加druid数据源依赖,生成的pom.xml如下... 查看详情

springboot、mybatis-plus、druid多数据源环境搭建

...类与连接串)。(本文阅读大概花费两分钟)技术条件:springboot2.5.3(即springframework5.3.9)MySQL5.7mybatis-plus3.5.0dynamic-datasource3.5.0druid1.2.9idea开发工具、maven3.3.91、导入相关依赖2、建立两个数据库mydb(表user)、db2(表t_class),并分... 查看详情

springboot2整合mybatis实例

本文主要讲解sb2和mybatis的整合要点。本文以表user为例。步骤:一、首先的前提:(共三步,只做一次)1.在pom.xml文件引入应用对mybatis的依赖:<!--引入starter--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <a... 查看详情

springboot:mybatis+druid数据访问(代码片段)

SpringBoot:Mybatis+Druid数据访问文章目录SpringBoot:Mybatis+Druid数据访问1、简介2、JDBC3、CRUD操作4、自定义数据源DruidDataSource1、配置Druid数据源监控2、配置Druidweb监控filter5、SpringBoot整合mybatis1、简介​对于数据访问层... 查看详情

springboot+mybatis+druid+pagehelper实现多数据源并分页

前言本篇文章主要讲述的是SpringBoot整合Mybatis、Druid和PageHelper并实现多数据源和分页。其中SpringBoot整合Mybatis这块,在之前的的一篇文章中已经讲述了,这里就不过多说明了。重点是讲述在多数据源下的如何配置使用Druid和PageHelpe... 查看详情

springboot系列七:springboot集成mybatis事物配置及使用druid数据源druid监控使用

一、MyBatis和druid简介  MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接... 查看详情

springboot2系列教程|springboot整合mybatis

前言如题,今天介绍SpringBoot与Mybatis的整合以及Mybatis的使用,本文通过注解的形式实现。什么是MybatisMyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取... 查看详情

springboot--整合mybatis+druid(代码片段)

...数据源为阿里德鲁伊并添加监控,其次是SpringBoot下使用Mybatis替换数据源为德鲁伊  首先在配置文件里配置好数据库连接的基本信息,如usernamepasswordurl等,重要的是把默认的type换成Druid。这样做数据源已经换成druid了,但是如... 查看详情

springboot2.1.1.release集成mybatis

SpringBoot2.1.1.RELEASE集成MyBatismaven工程:详细配置见:http://www.qchcloud.cn/system/article/show/63pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apac 查看详情