Springboot项目之mybatis-plus多容器分布式部署id重复问题之源码解析

mybatis-plus 3.3.2 部署多个pod id冲突问题

配置:

# 设置随机
mybatis-plus.global-config.worker-id: ${random.int(1,31)}
mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}

源码解析:MybatisSqlSessionFactoryBean

重点:new MybatisSqlSessionFactoryBuilder().build(targetConfiguration); -->IdWorker.setIdentifierGenerator(identifierGenerator);

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {final MybatisConfiguration targetConfiguration;// TODO 使用 MybatisXmlConfigBuilder 而不是 XMLConfigBuilderMybatisXMLConfigBuilder xmlConfigBuilder = null;if (this.configuration != null) {targetConfiguration = this.configuration;if (targetConfiguration.getVariables() == null) {targetConfiguration.setVariables(this.configurationProperties);} else if (this.configurationProperties != null) {targetConfiguration.getVariables().putAll(this.configurationProperties);}} else if (this.configLocation != null) {// TODO 使用 MybatisXMLConfigBuilderxmlConfigBuilder = new MybatisXMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);targetConfiguration = xmlConfigBuilder.getConfiguration();} else {LOGGER.debug(() -> "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");// TODO 使用 MybatisConfigurationtargetConfiguration = new MybatisConfiguration();Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);}// TODO 无配置启动所必须的this.globalConfig = Optional.ofNullable(this.globalConfig).orElseGet(GlobalConfigUtils::defaults);this.globalConfig.setDbConfig(Optional.ofNullable(this.globalConfig.getDbConfig()).orElseGet(GlobalConfig.DbConfig::new));// TODO 初始化 id-work 以及 打印骚东西targetConfiguration.setGlobalConfig(this.globalConfig);// TODO 自定义枚举类扫描处理if (hasLength(this.typeEnumsPackage)) {Set<Class<?>> classes;if (typeEnumsPackage.contains(StringPool.STAR) && !typeEnumsPackage.contains(StringPool.COMMA)&& !typeEnumsPackage.contains(StringPool.SEMICOLON)) {classes = scanClasses(typeEnumsPackage, null);if (classes.isEmpty()) {LOGGER.warn(() -> "Can't find class in '[" + typeEnumsPackage + "]' package. Please check your configuration.");}} else {classes = new HashSet<>();String[] typeEnumsPackageArray = tokenizeToStringArray(this.typeEnumsPackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Assert.notNull(typeEnumsPackageArray, "not find typeEnumsPackage:" + typeEnumsPackage);Stream.of(typeEnumsPackageArray).forEach(typePackage -> {try {Set<Class<?>> scanTypePackage = scanClasses(typePackage, null);if (scanTypePackage.isEmpty()) {LOGGER.warn(() -> "Can't find class in '[" + typePackage + "]' package. Please check your configuration.");} else {classes.addAll(scanTypePackage);}} catch (IOException e) {throw new MybatisPlusException("Cannot scan class in '[" + typePackage + "]' package", e);}});}// 取得类型转换注册器TypeHandlerRegistry typeHandlerRegistry = targetConfiguration.getTypeHandlerRegistry();classes.stream().filter(Class::isEnum).filter(MybatisEnumTypeHandler::isMpEnums).forEach(cls -> typeHandlerRegistry.register(cls, MybatisEnumTypeHandler.class));}Optional.ofNullable(this.objectFactory).ifPresent(targetConfiguration::setObjectFactory);Optional.ofNullable(this.objectWrapperFactory).ifPresent(targetConfiguration::setObjectWrapperFactory);Optional.ofNullable(this.vfs).ifPresent(targetConfiguration::setVfsImpl);if (hasLength(this.typeAliasesPackage)) {scanClasses(this.typeAliasesPackage, this.typeAliasesSuperType).stream().filter(clazz -> !clazz.isAnonymousClass()).filter(clazz -> !clazz.isInterface()).filter(clazz -> !clazz.isMemberClass()).forEach(targetConfiguration.getTypeAliasRegistry()::registerAlias);}if (!isEmpty(this.typeAliases)) {Stream.of(this.typeAliases).forEach(typeAlias -> {targetConfiguration.getTypeAliasRegistry().registerAlias(typeAlias);LOGGER.debug(() -> "Registered type alias: '" + typeAlias + "'");});}if (!isEmpty(this.plugins)) {Stream.of(this.plugins).forEach(plugin -> {targetConfiguration.addInterceptor(plugin);LOGGER.debug(() -> "Registered plugin: '" + plugin + "'");});}if (hasLength(this.typeHandlersPackage)) {scanClasses(this.typeHandlersPackage, TypeHandler.class).stream().filter(clazz -> !clazz.isAnonymousClass()).filter(clazz -> !clazz.isInterface()).filter(clazz -> !Modifier.isAbstract(clazz.getModifiers())).forEach(targetConfiguration.getTypeHandlerRegistry()::register);}if (!isEmpty(this.typeHandlers)) {Stream.of(this.typeHandlers).forEach(typeHandler -> {targetConfiguration.getTypeHandlerRegistry().register(typeHandler);LOGGER.debug(() -> "Registered type handler: '" + typeHandler + "'");});}if (!isEmpty(this.scriptingLanguageDrivers)) {Stream.of(this.scriptingLanguageDrivers).forEach(languageDriver -> {targetConfiguration.getLanguageRegistry().register(languageDriver);LOGGER.debug(() -> "Registered scripting language driver: '" + languageDriver + "'");});}Optional.ofNullable(this.defaultScriptingLanguageDriver).ifPresent(targetConfiguration::setDefaultScriptingLanguage);if (this.databaseIdProvider != null) {// fix #64 set databaseId before parse mapper xmlstry {targetConfiguration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));} catch (SQLException e) {throw new NestedIOException("Failed getting a databaseId", e);}}Optional.ofNullable(this.cache).ifPresent(targetConfiguration::addCache);if (xmlConfigBuilder != null) {try {xmlConfigBuilder.parse();LOGGER.debug(() -> "Parsed configuration file: '" + this.configLocation + "'");} catch (Exception ex) {throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);} finally {ErrorContext.instance().reset();}}targetConfiguration.setEnvironment(new Environment(MybatisSqlSessionFactoryBean.class.getSimpleName(),this.transactionFactory == null ? new SpringManagedTransactionFactory() : this.transactionFactory,this.dataSource));if (this.mapperLocations != null) {if (this.mapperLocations.length == 0) {LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");} else {for (Resource mapperLocation : this.mapperLocations) {if (mapperLocation == null) {continue;}try {XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());xmlMapperBuilder.parse();} catch (Exception e) {throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);} finally {ErrorContext.instance().reset();}LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");}}} else {LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");}final SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(targetConfiguration);// TODO SqlRunnerSqlHelper.FACTORY = sqlSessionFactory;// TODO 打印骚东西 Bannerif (globalConfig.isBanner()) {System.out.println(" _ _   |_  _ _|_. ___ _ |    _ ");System.out.println("| | |\\/|_)(_| | |_\\  |_)||_|_\\ ");System.out.println("     /               |         ");System.out.println("                        " + MybatisPlusVersion.getVersion() + " ");}return sqlSessionFactory;
}

idworker实战

其中mybatis-plus内置的ImadcnIdentifierGenerator方法,就已经提供了对idworker框架的支持。

升级版本:v3.4.0

  " + MybatisPlusVersion.getVersion() + " ");
}return sqlSessionFactory;

}


# idworker实战其中mybatis-plus内置的`ImadcnIdentifierGenerator`方法,就已经提供了对idworker框架的支持。升级版本:v3.4.0![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/6aac34ebf0f36867d15d889d56f55fd7.png)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql数据库查询

MYSQL数据库的搭建 今日目标&#xff1a; 1.搭建数据库 2.实现数据库的增删改查 00-回顾 #dos的常用指令 1. 切换盘符&#xff1a; 盘符名: 2. 切换上一级&#xff1a; cd ../ 3. 切换下一级&#xff1a; cd 目录名 4. 查看当前目录下的所有子目录和子文件&#xff1a; di…

光明源@智慧公厕赋能“厕所革命”主要体现在哪些方面?

当我们提及厕所&#xff0c;不再仅是简单的卫生设施&#xff0c;而是一种对生活品质的关怀与呵护。智慧公厕&#xff0c;作为厕所革命的引领者&#xff0c;以其独特的拟人魅力&#xff0c;彰显着人性化关怀的新风尚。今日&#xff0c;让我们一同探索&#xff0c;智慧公厕是如何…

数据库备份工具(实现数据定时覆盖)

数据库备份工具&#xff08;实现数据定时覆盖&#xff09; 永远热爱&#xff0c;永远执着&#xff01; 工具介绍 自动化测试数据库更新调度程序 这段 Python 脚本自动化了每天定时从生产数据库更新测试数据库的过程。它利用了 schedule 库来安排并执行每天指定时间的更新任务…

在for循环加判断条件当条件都满足时,同时显现的解决方法

一、代码示例 function fu(s) {str ;ste ;console.log(s);let Things s;for (let i 0; i < Things.length; i) {if (Things[i].pid kk) {console.log(Things[i].pid);ste <div class"commodity_nei"><div class"zxc_pic"><div cl…

[CISCN2019 总决赛 Day2 Web1]Easyweb ----不会编程的崽

CISCN的题质量还是很高的。 又是这熟悉的登陆界面。爆破&#xff1f;sql&#xff1f;还是xxe等。先看源码 估摸着也是sql注入。但似乎不是常规注入。同时扫描后台的结果应该也出来了&#xff0c;发现robots.txt 有点懵&#xff0c;后边看了大佬的wp才知道&#xff0c;提示的是*…

车载测试工具 canoe如何使用

其实canoe的使用非常的简单&#xff0c;结合自己的工作项目多多操作就可以了

openssl 升级1.1.1.1k 到 3.0.13

下载 https://www.openssl.org/source/ tar -zxvf openssl-3.0.13.tar.gzcd openssl-3.0.13/./config enable-fips --prefix/usr/local --openssldir/usr/local/opensslmake && make install 将原有openssl备份 mv /usr/bin/openssl /usr/bin/openssl.bak mv /usr/i…

LeetCode Python - 73. 矩阵置零

目录 题目描述解法方法一&#xff1a;数组标记方法二&#xff1a;原地标记 运行结果方法一方法二 题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;…

项目立项管理

目录 1.概述 2.项目建议与立项申请 3.项目可行性研究 3.1.内容 3.2.初步可行性研究 3.3.详细可行性研究 4.项目评估与决策 5.总结 1.概述 本文的目录结构参考了《信息系统项目管理师教程&#xff08;第四版&#xff09;》。 项目立项管理是一项全面评估准备投资工程的多…

Redis到底是多线程还是单线程?

Redis6.0之前&#xff1a;是单线程模式。 Redis6.0之后&#xff1a;Redis的IO线程是多线程&#xff0c;worker线程是单线程。 Redis6.0之前&#xff1a;单线程 Redis6.0之后&#xff1a;Redis的IO线程是多线程&#xff0c;worker线程是单线程。

适用于 Android 的 10 个优秀的数据恢复工具

在当今快节奏的数字时代&#xff0c;丢失 Android 设备中的重要数据可能是一场噩梦。无论是难忘的照片、重要的联系人还是重要的工作文档&#xff0c;您都需要一个可靠的恢复工具来恢复您的数据。值得庆幸的是&#xff0c;有许多高效的 Android 数据恢复工具可以帮助您恢复丢失…

【python】flask各种版本的项目,终端命令运行方式的实现

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

操作系统面经-多线程同步的四种方式

对于多线程程序来说&#xff0c;同步是指在一定的时间内只允许某一个线程来访问某个资源。而在此时间内&#xff0c;不允许其他的线程访问该资源。可以通过互斥锁&#xff08;Mutex&#xff09;、条件变量&#xff08;condition variable&#xff09;、读写锁&#xff08;reade…

XUbuntu22.04之跨平台日历工具(二百二十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

ChatGPT编程秘籍:轻松学习人工智能写作

ChatGPT无限次数:点击直达 html ChatGPT编程秘籍&#xff1a;轻松学习人工智能写作 引言 人工智能技术的发展给写作领域带来了革命性的变化&#xff0c;其中自然语言生成&#xff08;NLG&#xff09;技术的发展尤为引人注目。ChatGPT是一款基于大规模预训练模型的人工智能…

数据结构与算法-排序算法

1.顺序查找 def linear_search(iters, val):for i, v in enumerate(iters):if v val:return ireturn 2.二分查找 # 升序的二分查找 def binary_search(iters, val):left 0right len(iters)-1while left < right:mid (left right) // 2if iters[mid] val:return mid…

300.【华为OD机试】跳房子I(时间字符串排序—JavaPythonC++JS实现)

本文收录于专栏:算法之翼 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解代码C/C++题解代码JS题解代码四.代码讲解(Ja…

WSL2 设置桥接模式

文章目录 一、前言二、准备阶段三、环境配置3.1 Type-V管理器环境配置3.2 新增.wslconfig 文件 四、遇到的问题以及解决方案 一、前言 ​ 使用 wsl 的过程中&#xff0c;会出现 WSL 的IP地址 找不到&#xff0c;或者无法和计算机通讯&#xff0c;搞 嵌入式 的话&#xff0c;还…

网络原理(7)——以太网数据帧和DNS协议(数据链路层和应用层)

目录 一、以太网数据帧&#xff08;数据链路层&#xff09; 二、DNS协议(域名解析系统&#xff0c;应用层协议) 一、以太网数据帧&#xff08;数据链路层&#xff09; 以太网横跨了数据链路层和物理层&#xff0c;这里只做简单介绍&#xff0c;因为普通程序员用不到这一块&am…

数据结构——顺序表(C语言版)

顺序表是数据结构中最基本的一种线性表&#xff0c;它以一段连续的存储空间来存储数据元素&#xff0c;元素之间的顺序由它们在内存中的位置来决定。在C语言中&#xff0c;我们通常使用数组来实现顺序表。 目录 顺序表的结构定义 顺序表的基本操作 应用实例 顺序表的结构定义…