tags: multi-datasource java springboot
Одним предложением: при разработке Spring Boot подключение нескольких баз данных для операций чтения и записи с использованием нескольких наборов источников данных является наиболее прямым и простым способом.
1. Введение
В процессе разработки неизбежно одновременное использование нескольких баз данных.Обычные сценарии применения следующие:
- Сценарии высокопроизводительных баз данных: ведущий-ведомый, включая один главный и один подчиненный, один главный и несколько подчиненных и т. д., операции добавления, удаления и изменения в главной базе данных и операции чтения в подчиненной базе данных.
- Сценарий высокой доступности базы данных: главная/резервная, включая один к одному резервную, мультимастерную и мультирезервную и т. д., можно переключать, когда доступ к базе данных недоступен.
- Бизнес-обработка однородных или разнородных данных: данные, подлежащие обработке, хранятся в разных базах данных, в том числе однородных (таких как MySQL) и разнородных (таких как одна MySQL, а PG или Oracle).
Как использовать Spring Boot для обработки чтения и записи нескольких баз данных, обычно существуют следующие стратегии:
- Несколько наборов источников данных: то есть, чтобы установить набор логики обработки данных для базы данных, каждый набор баз данных включает конфигурацию источника данных, фабрику сеансов ( sessionFactory ), соединение, операцию SQL, сущность. Каждый набор баз данных независим друг от друга.
- Динамические источники данных: определенное количество источников данных совместно используют фабрику сеансов, и источники данных динамически выбираются для подключения и операций SQL в соответствии с условиями.
- Параметризованный источник данных изменения: добавьте источники данных в соответствии с параметрами и переключите источники данных, количество источников данных неизвестно. Обычно используется для управления несколькими базами данных.
В этой серии статей "Получение нескольких источников данных SpringBoot" будут описаны вышеуказанные стратегии. Эта статья является первой статьей: "Несколько источников данных", в которой в основном используется сценарий ведущий-подчиненный в качестве примера и комбинируется код для реализации реализации нескольких Источники данных Опишите, включая сборку проекта Spring Boot + MyBatis Plus, конфигурацию с несколькими источниками данных, обработку нескольких источников данных и логику использования.
в этой статьеобразец кода:https://github.com/mianshenglee/my-example/tree/master/multi-datasource
, читатель может посмотреть его вместе.
2. Операционная среда
- Операционная среда JAVA:
JDK1.8
- Spring Boot:
2.2.2.RELEASE
- MyBatis Plus:
3.3.0
- Среда разработки:
IDEA
- Инструмент сборки Maven:
3.3.9
- MySQL :
5.6.26
-
Lombok:
1.18.10
3. Несколько наборов источников данных
Несколько наборов источников данных, как следует из названия, каждая база данных имеет набор независимых операций. Снизу вверх база данных, фабрика сеансов, операция DAO и сервисный уровень — все это независимые наборы, как показано ниже:
В этом примере есть две базы данных, одна главная и одна подчиненная, в каждой из которых есть таблицаtest_user
, структура таблицы одинаковая, для удобства пояснения данные в двух таблицах разные. Обе структуры таблиц доступны вобразец кодасерединаsql
полученный из справочника.
3.1 Создание проекта Spring Boot
3.1.1 Инициализация проекта Spring Boot
использоватьspring.ioЧтобы собрать начальный проект Spring Boot, выберите следующие компоненты:
- Ломбок: используется для упрощения операций
- Spring Configuration Processor: процессор файлов конфигурации
- Spring Web: для создания веб-сервисов
- Драйвер MySQL: драйвер базы данных
3.1.2 Добавление зависимости MyBatis Plus
MyBatis PlusЭто усовершенствование MyBatis, упрощающее операции DAO и повышающее эффективность операций с базой данных. Зависимости следующие:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
3.1.3 Добавить структуру пакета
В основном добавьте следующие пакеты:
├─config ---------------------------------- // 数据源配置
├─controller ------------------------------ // web服务
├─entity ---------------------------------- // 实体类
│ ├─master
│ └─slave
├─mapper ---------------------------------- // dao操作类
│ ├─master
│ └─slave
└─vo -------------------------------------- // 视图返回对象
Примечание:
- Опустите сервисный уровень из-за простоты примера.
- Классы сущностей и мапперы делятся на главные и подчиненные.
3.2 Несколько наборов источников данных
3.2.1 Информация о подключении к независимой базе данных
Файл конфигурации по умолчанию для Spring Boot:application.properties
, поскольку есть две конфигурации базы данных, рекомендуется настроить базу данных независимо, поэтому добавьте файл конфигурацииjbdc.properties
, добавьте следующую пользовательскую конфигурацию базы данных master-slave:
# master
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.jdbc-url=jdbc:mysql://localhost:3306/mytest?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.master.username=root
spring.datasource.master.password=111111
# slave
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.jdbc-url=jdbc:mysql://localhost:3306/my_test1?useSSL=false&serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.datasource.slave.username=root
spring.datasource.slave.password=111111
3.2.2 Несколько наборов конфигурации источника данных
С информацией о подключении к источнику данных источник данных необходимо внедрить в Spring. Поскольку каждая база данных использует отдельный набор соединений с базой данных, соединение с базой данных используетSqlSession
установить сеансовое соединение,SqlSession
ОтSqlSessionFactory
генерировать. Поэтому необходимо настроитьSqlSessionFactory
. Следующие операцииconfig
Под содержанием:
(1) ДобавитьDataSourceConfig
Файл конфигурации, ввод источника данных master-slave
@Configuration
@PropertySource("classpath:config/jdbc.properties")
public class DatasourceConfig {
@Bean("master")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource(){
return DataSourceBuilder.create().build();
}
@Bean("slave")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource(){
return DataSourceBuilder.create().build();
}
}
- аннотация
PropertySource
Укажите файл с информацией о конфигурации- аннотация
ConfigurationProperties
Укажите префикс конфигурации master-slave- Укажите имена bean-компонентов главного и подчиненного источников данных соответственно как
master
,slave
(2) ДобавитьMasterMybatisConfig
Конфигурационный файл, внедренный в мастерSqlSessionFactory
@Configuration
@MapperScan(basePackages = "me.mason.demo.basicmultidatasource.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterMybatisConfig {
/**
* 注意,此处需要使用MybatisSqlSessionFactoryBean,不是SqlSessionFactoryBean,
* 否则,使用mybatis-plus的内置函数时就会报invalid bound statement (not found)异常
*/
@Bean("masterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("master") DataSource dataSource) throws Exception {
// 设置数据源
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(dataSource);
//mapper的xml文件位置
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String locationPattern = "classpath*:/mapper/master/*.xml";
mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
//对应数据库的entity位置
String typeAliasesPackage = "me.mason.demo.basicmultidatasource.entity.master";
mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
return mybatisSqlSessionFactoryBean.getObject();
}
}
- аннотация
MapperScan
Укажите те, которые находятся под пакетомmapper
Используйте этот источник данных и укажите, какой использоватьSqlSessionFactory
, обратите внимание, что здесьsqlSessionFactoryRef
То есть инжектор в этой конфигурацииSqlSessionFactory
.- Задает указанный источник данных, здесь именованный
master
источник данных, использованиеQualifier
указано.- Если у маппера, соответствующего MyBatis Plus, есть пользовательский mapper.xml, используйте
setMapperLocations
указано.- Если вам нужно псевдоним объекта, используйте
setTypeAliasesPackage
указано.
(3) ДобавитьSlaveMybatisConfig
Файл конфигурации, внедренный в SlaveSqlSessionFactory
В соответствии с (2), просто измените ведущее устройство на ведомое.
3.2.3 Несколько наборов сущностей
В конфигурации MyBatis параметры сущностиtypeAliases
Конфигурацию xml можно упростить, как упоминалось ранее, с помощьюtypeAliasesPackage
Установите путь объекта, вentity
Устанавливается отдельно под пакетомmaster
иslave
Пакет хранит сущности таблицы, соответствующие двум библиотекам, и использует Lombok для упрощения операций с сущностями. следующее:
@Data
@TableName("test_user")
public class MasterTestUser implements Serializable {
private static final long serialVersionUID = 1L;
/** id */
private Long id;
/** 姓名 */
private String name;
...
}
3.2.4 Несколько наборов операций Mapper
существуетmapper
Под пакет добавить их отдельноmaster
иslave
пакет, в котором хранится Mapper, соответствующий двум библиотекам.Поскольку сам MyBatis Plus уже содержит основные операции CRUD, во многих случаях его можно настроить без файлов xml. Если вам нужно настроить операцию, вам нужно объединить xml-файл, и при этом вам нужно указать каталог, в котором находится соответствующий xml-файл. следующее:
@Repository
public interface MasterTestUserMapper extends BaseMapper<MasterTestUser> {
/**
* 自定义查询
* @param wrapper 条件构造器
*/
List<MasterTestUser> selectAll(@Param(Constants.WRAPPER)Wrapper<MasterTestUser> wrapper);
}
Mapper, соответствующий ведомому, похож на этот
3.2.5 Несколько наборов XML-файлов картографа
Путь к XML-файлу Mapper по умолчанию MyBatis Plus:classpath*:/mapper/**/*.xml
,Сейчасresources/mapper
, и установите то же самоеmaster
иslave
Каталог для хранения соответствующих XML-файлов преобразователя соответственно. Ниже приведены настраиваемые действия для мастера:
<mapper namespace="me.mason.demo.basicmultidatasource.mapper.master.MasterTestUserMapper">
<select id="selectAll" resultType="masterTestUser">
select * from test_user
<if test="ew!=null">
${ew.customSqlSegment}
</if>
</select>
</mapper>
3.3 Использование нескольких источников данных
После приведенных выше нескольких наборов конфигураций источников данных вы можете узнать, с какой базой данных вам нужно работать, и вы можете напрямую использовать соответствующий преобразователь для выполнения операций CRUD. Ниже приведены две библиотеки, которые запрашиваются в контроллере по отдельности, и полученные данные возвращаются вместе:
@RestController
@RequestMapping("/user")
public class TestUserController {
@Autowired
private MasterTestUserMapper masterTestUserMapper;
@Autowired
private SlaveTestUserMapper slaveTestUserMapper;
/**
* 查询全部
*/
@GetMapping("/listall")
public Object listAll() {
//master库,自定义接口查询
QueryWrapper<MasterTestUser> queryWrapper = new QueryWrapper<>();
List<MasterTestUser> resultData = masterTestUserMapper.selectAll(queryWrapper.isNotNull("name"));
//slave库,mp内置接口
List<SlaveTestUser> resultDataSlave = slaveTestUserMapper.selectList(null);
//返回
Map<String, Object> result = new HashMap<>();
result.put("master" , resultData);
result.put("slave" , resultDataSlave);
return ResponseResult.success(result);
}
}
- Используйте аннотацию Autowired для внедрения соответствующего картографа.
- Используйте маппер соответствующей базы данных для бизнес-операций
- Выполнение соответствующих операций в базе данных в соответствии с бизнесом, например, только операции добавления, удаления и изменения в главном устройстве и операции только для чтения в подчиненном устройстве.
На данный момент реализация нескольких источников данных завершена.Текущий пример - две однородные базы данных.Конечно, если есть разнородные базы данных или более двух баз данных, метод обработки тот же, но источник данных увеличивается на 1. Просто набор.
4. Преимущества и недостатки
Из приведенного выше описания мы можем обобщить преимущества и недостатки использования нескольких наборов источников данных для операций с несколькими базами данных.
4.1 Преимущества
- Просто и понятно: библиотека соответствует набору методов обработки, которые легко понять.
- Соблюдайте принцип открытости-закрытости (OCP): схема разработки говорит нам, что она открыта для расширения, закрыта для модификации и добавляется еще одна база данных.Исходный набор не нужно менять, просто добавьте его.
4.2 Недостатки
- Пустая трата ресурсов: Напишите набор операций для каждого источника данных, а ресурсы, подключенные к базе данных, также независимы, занимая такое же количество ресурсов.
SqlSessionFactory
Это фабрика. Рекомендуется использовать один экземпляр, который можно полностью использовать повторно. Нет необходимости создавать несколько экземпляров. Вам нужно только изменить источник данных. Это то же самое, что многопоточность и использование пулов потоков для снизить потребление ресурсов. - Избыточность кода: Как видно из предыдущей конфигурации с несколькими источниками данных, фактически многие операции ведущего и ведомого совпадают, но изменено имя, что вызовет избыточность кода.
- Недостаток гибкости: Соответствующие мапперы нужно вводить во все места, которые нужно использовать.Для многих операций по-разному выбирается только источник данных, а логика кода непротиворечива. Кроме того, в случае одного главного и нескольких подчиненных относительно сложно выполнять балансировку нагрузки на несколько подчиненных библиотек.
Из-за вышеперечисленных недостатков есть еще возможности для улучшения. Итак, есть динамический источник данных.Что касается того, как реализовать динамический источник данных, он будет разбит в следующий раз.
5. Резюме
В этой статье проводится предварительное обсуждение работы с несколькими базами данных и объясняется стратегия использования нескольких наборов источников.В сочетании с примерами кода master-slave создается проект Spring Boot + MyBatis Plus, настраиваются несколько источников данных и Mapper используется для операций с несколькими источниками данных и, наконец, суммирует преимущества и недостатки нескольких наборов источников данных. Я надеюсь, что у вас может сложиться предварительное впечатление о работе с несколькими источниками данных.
Эта статья сопровождаетсяобразец кода, если вам интересно, вы можете запустить пример, чтобы почувствовать это.
использованная литература
-
Конфигурация базы данных Spring master-slave и принцип динамического переключения источников данных:
https://www.liaoxuefeng.com/article/1182502273240832
-
Компромисс между несколькими источниками данных и динамическими источниками данных:
https://juejin.cn/post/6844903661655572494
-
Поговорите о загрузке источника данных Spring Boot и его простой реализации нескольких источников данных.:
https://juejin.cn/post/6844903817260056589
-
Spring Boot и MyBatis реализуют несколько источников данных и динамическое переключение источников данных.:
https://juejin.cn/post/6844903566717485069
Прошлые статьи
- Знания, необходимые для разработки Java: динамический прокси
- Лучшие книги для чтения в 2019 году
- Springboot + apache для внешнего и внутреннего интерфейса, отдельное развертывание https
- Корпоративная практика вывода журнала Springboot + logback (ниже)
- Корпоративная практика вывода журнала Springboot + logback (включена)
Мой официальный аккаунт (поискMason技术记录
) для более технических записей: