«Это первый день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г.".
- 💬 Если статья была вам полезна,Добро пожаловать, чтобы подписаться, поставить лайк, добавить в избранное (один клик три раза) и подписаться на колонку.
🚐 1. Введение
-
Привет всем, меня зовут Сяочэн, прежде чем я это узнал, последнее обновление было более 20 дней назад! На самом деле, это время не было праздным,
一个是在梳理之前的文章知识和资源,用于搭建技术圈子,另外一个就是在思考自己的一个输出方向,社区发展得很迅速,热榜各种各类的文章都有,深思熟虑后,还是坚持文章在精不在多,质量标准更加重要,所以今后博文的方向会更加偏向实战和经验,争取分享更加有价值的博文!
-
如果文章对你有帮助,可以帮忙一键三连和专栏订阅哦!
После этого периода планирования технический кружок оформился! Заинтересованные и единомышленники могут проверить введение технического кружка в левой панели навигации и с нетерпением ждут вашего присоединения! -
В этой статье основное внимание уделяется знанию коллекции SpringBoot MyBatis и MyBatis-Plus для интеграции нескольких источников данных!
🚅 2. Рекомендация колонки
Совесть рекомендует:Следующие связанные технические колонки по-прежнему публикуются бесплатно, вы можете помочь подписаться!
знание JAVA на продвинутом уровне
🚔 3. Что нужно знать об интеграции нескольких источников данных
1. Когда будут использоваться несколько источников данных?
Появление и применение технологии должно быть связано с решением некоторых существующих проблем.Распространенные сценарии появления нескольких источников данных следующие:
(1)、与第三方对接时,有些合作方并不会为了你的某些需求而给你开发一个功能,他们可以提供给你一个可以访问数据源的只读账号,你需要获取什么数据由你自己进行逻辑处理,这时候就避免不了需要进行多数据源整合了。
(2)、业务数据达到了一个量级,使用单一数据库存储达到了一个瓶颈,需要进行分库分表等操作进行数据管理,在操作数据时,不可避免的涉及到多数据源问题。
2. Каковы способы интеграции нескольких источников данных?
Просмотрел много материалов в интернете, и обнаружил, что методы интеграции не что иное, как следующее:
(1), используйте метод субподряда, настройте разные файлы MapperScan и mapper для разных источников данных
(2), используйте метод нарезки АОП для реализации динамического переключения источников данных (если вы не очень хорошо знакомы с АОП, пожалуйста, ознакомьтесь с моей предыдущей статьей, эти знания вам знакомы! [Что такое аспектно-ориентированное программирование?])
(3) использование агентов базы данных промежуточного программного обеспечения, таких как другие Mycat
3. Разница между разными методами
(1) Метод субподряда может интегрировать JTA (JAVA Transactional API) для реализации распределенных транзакций, но реализация всего процесса относительно сложна.
(2) Недостатком динамической конфигурации источников данных АОП является то, что он не может выполнять глобальные распределенные транзакции, поэтому, если он подключен только к сторонним источникам данных и не требует обеспечения распределенных транзакций, его можно использовать в качестве вариант.
(3),使用数据库代理中间件方式是现在比较流行的一种方式,很多大厂也是使用这种方式
, разработчикам не нужно уделять слишком много внимания вопросам, не связанным с бизнесом, все они обрабатываются промежуточным программным обеспечением прокси базы данных.Большое количество общих агрегаций данных, транзакций и переключения источников данных обрабатывается промежуточным программным обеспечением. . Производительность промежуточного программного обеспечения аналогична производительности промежуточного программного обеспечения. Мощность процессора будет напрямую определять производительность чтения и записи приложения. Наиболее распространенными являются Mycat, TDDL и т. д.现在阿里出了100%自研的分布式数据库OceanBase,从最底层支持分布式,性能也非常强大,大家感兴趣的可以去了解下!
4. Метод собственно боевого отбора в данной статье
В связи с необходимостью интеграции нескольких источников данных на этот раз необходимо对接第三方的数据
, в настоящее время не связано с проблемами распределенных транзакций,所以本文实战整合多数据源使用的方式是【分包方式】实现简单的多数据源整合,至于其他方式和分布式事务的坑,后面再慢慢填吧(o(╥﹏╥)o)!
🚢 В-четвертых, SpringBoot+MyBatis интегрирует несколько источников данных
🔴 4.1 Описание
Этот кейс включает в себя много кода, поэтому размещена только часть статьи.Все коды кейсов загружены в Gitee, и те, кому это нужно, могут посетить напрямую: [SpringBoot объединяет MyBatis для интеграции нескольких источников данных.], структура проекта следующая:
🟠 4.2 включает пакеты зависимостей
- spring-boot-starter-web -- веб-поддержка
- mybatis-spring-boot-starter -- springboot интегрирует зависимости mybatis
- mysql-connector-java -- драйвер данных mysql
- lombok -- автоматически генерировать пакеты зависимостей для общих методов классов сущностей
- hutool-all — распространенный способ инкапсуляции зависимостей
<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.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.5</version>
</dependency>
🟡 4.3 Конфигурация проекта
# 项目启动端口
server:
port: 9090
# 项目 名称
spring:
application:
name: multi-datasource-instance
datasource:
# 主数据库
master:
# 注意,整合多数据源时如果使用springboot默认的数据库连接池Hikari,指定连接数据使用的是jdbc-url而不是url属性
jdbc-url: jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 副数据库
slave:
# 注意,整合多数据源时如果使用springboot默认的数据库连接池Hikari,指定连接数据使用的是jdbc-url而不是url属性
jdbc-url: jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
🟢 4.4 Запись первичной и вторичной конфигурации источника данных базы данных
1、主数据源相关配置:
В основном для указания основного источника данных, отсканированного адреса картографа, менеджера транзакций и другой информации.
@Configuration
// 指定主数据库扫描对应的Mapper文件,生成代理对象
@MapperScan(basePackages ="com.diary.it.multi.datasource.mapper" ,sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
// mapper.xml所在地址
private static final String MAPPER_LOCATION = "classpath*:mapper/*.xml";
/**
* 主数据源,Primary注解必须增加,它表示该数据源为默认数据源
* 项目中还可能存在其他的数据源,如获取时不指定名称,则默认获取这个数据源,如果不添加,则启动时候回报错
*/
@Primary
@Bean(name = "masterDataSource")
// 读取spring.datasource.master前缀的配置文件映射成对应的配置对象
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource dataSource() {
DataSource build = DataSourceBuilder.create().build();
return build;
}
/**
* 事务管理器,Primary注解作用同上
*/
@Bean(name = "masterTransactionManager")
@Primary
public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* session工厂,Primary注解作用同上
*/
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION));
return sessionFactoryBean.getObject();
}
}
2、副数据源相关配置:
В основном укажите источник данных, отсканированный адрес картографа, менеджер транзакций и другую информацию.
@Configuration
// 指定从数据库扫描对应的Mapper文件,生成代理对象
@MapperScan(basePackages = "com.diary.it.multi.datasource.mapper2", sqlSessionFactoryRef = "slaveSqlSessionFactory")
public class SlaveDataSourceConfig {
// mapper.xml所在地址
private static final String MAPPER_LOCATION = "classpath*:mapper2/*.xml";
/**
* 数据源
*/
@Bean(name = "slaveDataSource")
// 读取spring.datasource.slave前缀的配置文件映射成对应的配置对象
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource dataSource() {
DataSource build = DataSourceBuilder.create().build();
return build;
}
/**
* 事务管理器
*/
@Bean(name = "slaveTransactionManager")
public PlatformTransactionManager dataSourceTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* session工厂
*/
@Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(SlaveDataSourceConfig.MAPPER_LOCATION));
return sessionFactoryBean.getObject();
}
}
🔵 4.5 Результат исполнения
После выполнения вышеперечисленных шагов, так же, как мы обычно пишем бизнес-логику, пишем бизнес-логику в сервисе, пишем операторы sql в маппере и т.д. Давайте посмотрим на результаты выполнения!
🟣 4.6 Проблемы, возникающие при интеграции
Прочитав приведенный выше учебник, вы обнаружили, что интеграция нескольких источников данных на самом деле довольно проста!但是,完全按照教学流程整合还是遇到各种问题的现象真的太常见了,下面博主就总结下整合中遇到的各种问题
, если вы также столкнулись с этим в процессе интеграции, вы можете напрямую следить за решением блогера (будьте внимательны!).
Вопрос 1. Требуется jdbcUrl с исключением driverClassName
причина:Пул соединений с базой данных по умолчанию после SpringBoot2.x — это HikariCP (известный как самый быстрый в истории и с самой высокой производительностью),HikariCP连接池中命名规则和其他的连接池不太一样,指定连接数据库的地址时,它使用的是jdbc-url而不是url,所以如果我们不指定数据库连接池如druid而使用springboot默认的连接池的话,需要将配置中连接数据库的url改成jdbc-url属性。
Вопрос 2. Недопустимое связанное выражение (не найдено) возникает исключение
причина:
(1) При определении информации о конфигурации источника данных расположение файла mapper.xml, сканируемого SqlSessionFactoryBean, не указывается, а именно sessionFactoryBean.setMapperLocations(xxx).
(2), путь, соответствующий атрибуту пространства имен в файле MapPer.xml, является неточным или идентификатором и атрибутом параметратерий соответствующего метода, неверно
(3), возвращаемое методом xxxMapper.java значение List, а элемент select неправильно настраивает ResultMap или настраивает только ResultType
Вопрос 3. Исключение требует один bean-компонент, но найдено 2
причина:Поскольку мы использовали аннотацию MapperScan для сканирования соответствующего файла mapper.java при указании конфигурации первичного и вторичного источников данных, отсканированный файл mapper.java уже сгенерировал прокси-класс для контейнера Spring.Если мы используем MapperScan для сканирования в класс запуска в это время Возникнет вышеуказанная проблема (Странно то, что об этой проблеме не будет сообщено, когда я поменяю компьютер, поэтому, если эта проблема возникнет, решите ее в соответствии с этим решением.)
Вопрос. 4. Почему первичная аннотация добавляется к классу конфигурации основных источников данных?
причина:Из-за интеграции нескольких источников данных в контейнер Spring будут внедрены несколько экземпляров DataSource, PlatformTransactionManager и т. д. Роль основной аннотации:当我们使用自动配置的方式如Autowired注入Bean时,如果这个Bean有多个候选者,如果其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动配置的值。
Вопрос 5. Разница между com.mysql.jdbc.Driver и com.mysql.cj.jdbc.Driver
причина:Внимательные друзья обнаружат, что значением атрибута driver-class-name в конфигурации базы данных является com.mysql.cj.jdbc.Driver,Фактически, com.mysql.jdbc.Driver управляется mysql-connector-java 5, а com.mysql.cj.jdbc.Driver управляется mysql-connector-java 6 и более поздними базами данных., если вы используете драйвер базы данных mysql после версии 6.x и продолжаете использовать com.mysql.jdbc.Driver, он будет сообщать о том, что он устарел (устаревший) при запуске, а драйвер после mysql6.x должен указать часовой пояс serverTimezone:
🚲 5. SpringBoot+Mybatis-Plus объединяет несколько источников данных
Вышеупомянутый Mybatis использует субподряд для интеграции нескольких источников данных, что несколько проблематично, но использование MyBatis-Plus относительно просто,MyBatis-Plus官方就支持了多数据源,使用的时候只需要一个注解就可以实现,整合多数据源的时候推荐使用该种方式。
🟥 5.1 Описание
Этот кейс включает в себя много кода, поэтому размещена только часть статьи.Все коды кейсов загружены в Gitee, и те, кому это нужно, могут посетить напрямую: [Настоящий бой — SpringBoot в сочетании с MyBatis-Plus для интеграции нескольких источников данных],mybatis-plus поддержка нескольких источников данных:
项目结构如下:
🟧 5.2 Используемые зависимости
- spring-boot-starter-web -- веб-поддержка
- MyBatis-Plus-Boot-Starter - SpringBoot объединяет зависимости MyBatis-Plus
- dynamic-datasource-spring-boot-starter -- mybatis-plus управляет зависимостями источников данных
- mysql-connector-java -- драйвер данных mysql
- lombok -- автоматически генерировать пакеты зависимостей для общих методов классов сущностей
- hutool-all — распространенный способ инкапсуляции зависимостей
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.5</version>
</dependency>
🟨 5.3 Связанная конфигурация
# 启动端口
server:
port: 9091
# 项目名称
spring:
application:
name: multi-datasource-instance2
datasource:
# 采用动态选取
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
# 主数据库
master:
url: jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 副数据库
slave:
url: jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
🟩 5.4 Как пользоваться
🟦 5.5 результат выполнения
🚀 六, написание в финале
Весь код в статье выложен на Gitee, при необходимости можете забрать (позже он будет выложен на CSDN для бесплатного скачивания), не забудьте поставить звездочку, если поможет, будет больше практических статей позже (顺便透露下下篇文章是:关于Ftp文件上传到服务器和下载到本地的实战
), проект Gitee через поезд выглядит следующим образом:
1. SpringBoot+MyBatis интегрирует несколько источников данных
2. SpringBoot+MyBatis-Plus объединяет несколько источников данных
В последнее время я занят разбором ресурсов техкружка, поэтому обновлений относительно мало.Сейчас ресурсы техкруга предварительно разобраны, и скорость обновления будет возобновлена одна за другой.【技术圈子】中有免费面试资源、简历模板、年终汇报PPT、CSDN VIP下载资源等等,感兴趣者可以查看主页领取