Java连接TDengine和MySQL双数据源
git文件地址:项目首页 - SpringBoot连接TDengine和MySQL双数据源:SpringBoot连接TDengine和MySQL双数据源 - GitCode
1、yml配置
spring:datasource:druid:mysql:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/testusername: rootpassword: 1234type: com.alibaba.druid.pool.DruidDataSourcetdengine:driver-class-name: com.taosdata.jdbc.rs.RestfulDriverurl: jdbc:TAOS-RS://localhost:6041/test?&timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8username: rootpassword: 1234type: com.alibaba.druid.pool.DruidDataSource
2、pom依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.15</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-extension</artifactId><version>3.5.3.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.3.1</version></dependency><!-- 动态数据源 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.3-jre</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.6.3</version></dependency><dependency><groupId>com.taosdata.jdbc</groupId><artifactId>taos-jdbcdriver</artifactId><version>3.2.7</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.3.8</version></dependency>
</dependencies>
3、重写SqlSession
package com.example.testtdengine.config.db;import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.*;
import org.mybatis.spring.MyBatisExceptionTranslator;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.Assert;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.List;
import java.util.Map;import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;
import static org.mybatis.spring.SqlSessionUtils.*;public class CustomSqlSessionTemplate extends SqlSessionTemplate {private final SqlSessionFactory sqlSessionFactory;private final ExecutorType executorType;private final SqlSession sqlSessionProxy;private final PersistenceExceptionTranslator exceptionTranslator;private Map<Object, SqlSessionFactory> targetSqlSessionFactories;private SqlSessionFactory defaultTargetSqlSessionFactory;/*** 通过Map传入** @param targetSqlSessionFactories*/public void setTargetSqlSessionFactories(Map<Object, SqlSessionFactory> targetSqlSessionFactories) {this.targetSqlSessionFactories = targetSqlSessionFactories;}public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory) {this.defaultTargetSqlSessionFactory = defaultTargetSqlSessionFactory;}public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());}public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));}public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,PersistenceExceptionTranslator exceptionTranslator) {super(sqlSessionFactory, executorType, exceptionTranslator);this.sqlSessionFactory = sqlSessionFactory;this.executorType = executorType;this.exceptionTranslator = exceptionTranslator;this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),new Class[]{SqlSession.class},new SqlSessionInterceptor());this.defaultTargetSqlSessionFactory = sqlSessionFactory;}//通过DataSourceContextHolder获取当前的会话工厂@Overridepublic SqlSessionFactory getSqlSessionFactory() {String dataSourceKey = DbContextHolder.getDbType();SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactories.get(dataSourceKey);if (targetSqlSessionFactory != null) {return targetSqlSessionFactory;} else if (defaultTargetSqlSessionFactory != null) {return defaultTargetSqlSessionFactory;} else {Assert.notNull(targetSqlSessionFactories, "Property 'targetSqlSessionFactories' or 'defaultTargetSqlSessionFactory' are required");Assert.notNull(defaultTargetSqlSessionFactory, "Property 'defaultTargetSqlSessionFactory' or 'targetSqlSessionFactories' are required");}return this.sqlSessionFactory;}@Overridepublic Configuration getConfiguration() {return this.getSqlSessionFactory().getConfiguration();}public ExecutorType getExecutorType() {return this.executorType;}public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {return this.exceptionTranslator;}/*** {@inheritDoc}*/public <T> T selectOne(String statement) {return this.sqlSessionProxy.<T>selectOne(statement);}/*** {@inheritDoc}*/public <T> T selectOne(String statement, Object parameter) {return this.sqlSessionProxy.<T>selectOne(statement, parameter);}/*** {@inheritDoc}*/public <K, V> Map<K, V> selectMap(String statement, String mapKey) {return this.sqlSessionProxy.<K, V>selectMap(statement, mapKey);}/*** {@inheritDoc}*/public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {return this.sqlSessionProxy.<K, V>selectMap(statement, parameter, mapKey);}/*** {@inheritDoc}*/public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {return this.sqlSessionProxy.<K, V>selectMap(statement, parameter, mapKey, rowBounds);}/*** {@inheritDoc}*/public <E> List<E> selectList(String statement) {return this.sqlSessionProxy.<E>selectList(statement);}/*** {@inheritDoc}*/public <E> List<E> selectList(String statement, Object parameter) {return this.sqlSessionProxy.<E>selectList(statement, parameter);}/*** {@inheritDoc}*/public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {return this.sqlSessionProxy.<E>selectList(statement, parameter, rowBounds);}/*** {@inheritDoc}*/public void select(String statement, ResultHandler handler) {this.sqlSessionProxy.select(statement, handler);}/*** {@inheritDoc}*/public void select(String statement, Object parameter, ResultHandler handler) {this.sqlSessionProxy.select(statement, parameter, handler);}/*** {@inheritDoc}*/public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);}/*** {@inheritDoc}*/public int insert(String statement) {return this.sqlSessionProxy.insert(statement);}/*** {@inheritDoc}*/public int insert(String statement, Object parameter) {return this.sqlSessionProxy.insert(statement, parameter);}/*** {@inheritDoc}*/public int update(String statement) {return this.sqlSessionProxy.update(statement);}/*** {@inheritDoc}*/public int update(String statement, Object parameter) {return this.sqlSessionProxy.update(statement, parameter);}/*** {@inheritDoc}*/public int delete(String statement) {return this.sqlSessionProxy.delete(statement);}/*** {@inheritDoc}*/public int delete(String statement, Object parameter) {return this.sqlSessionProxy.delete(statement, parameter);}/*** {@inheritDoc}*/public <T> T getMapper(Class<T> type) {return getConfiguration().getMapper(type, this);}/*** {@inheritDoc}*/public void commit() {throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");}/*** {@inheritDoc}*/public void commit(boolean force) {throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");}/*** {@inheritDoc}*/public void rollback() {throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");}/*** {@inheritDoc}*/public void rollback(boolean force) {throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");}/*** {@inheritDoc}*/public void close() {throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");}/*** {@inheritDoc}*/public void clearCache() {this.sqlSessionProxy.clearCache();}/*** {@inheritDoc}*/public Connection getConnection() {return this.sqlSessionProxy.getConnection();}/*** {@inheritDoc}** @since 1.0.2*/public List<BatchResult> flushStatements() {return this.sqlSessionProxy.flushStatements();}/*** Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also* unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to* the {@code PersistenceExceptionTranslator}.*/private class SqlSessionInterceptor implements InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {final SqlSession sqlSession = getSqlSession(CustomSqlSessionTemplate.this.getSqlSessionFactory(),CustomSqlSessionTemplate.this.executorType,CustomSqlSessionTemplate.this.exceptionTranslator);try {Object result = method.invoke(sqlSession, args);if (!isSqlSessionTransactional(sqlSession, CustomSqlSessionTemplate.this.getSqlSessionFactory())) {sqlSession.commit(true);}return result;} catch (Throwable t) {Throwable unwrapped = unwrapThrowable(t);if (CustomSqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {Throwable translated = CustomSqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);if (translated != null) {unwrapped = translated;}}throw unwrapped;} finally {closeSqlSession(sqlSession, CustomSqlSessionTemplate.this.getSqlSessionFactory());}}}
}
4、设置切面
@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect {@Pointcut("execution(* com.example.testtdengine.mapper.mysql..*.*(..))")private void mysqlAspect() {}@Pointcut("execution(* com.example.testtdengine.mapper.tdengine..*.*(..))")private void tdengineAspect() {}@Before("mysqlAspect()")public void mysql() {log.info("切换到mysql 数据源...");DbContextHolder.setDbType(DBTypeEnum.mysql);}@Before("tdengineAspect()")public void tdengine() {log.info("切换到tdengine 数据源...");DbContextHolder.setDbType(DBTypeEnum.tdengine);}@After("mysqlAspect()")public void clear1() {log.info("清除mysql数据源...");DbContextHolder.clearDbType();}@After("tdengineAspect()")public void clear2() {log.info("清除tdengine数据源...");DbContextHolder.clearDbType();}}
5、DBContextHolder使用ThreadLocal将数据源连接存储在当前线程的threadlocals(ThreadLocalMap)中,在连接数据库时自动获取当前线程对于的数据源
package com.example.testtdengine.config.db;public class DbContextHolder {private static final ThreadLocal contextHolder = new ThreadLocal<>();/*** 设置数据源** @param dbTypeEnum*/public static void setDbType(DBTypeEnum dbTypeEnum) {contextHolder.set(dbTypeEnum.getValue());}/*** 取得当前数据源** @return*/public static String getDbType() {return (String) contextHolder.get();}/*** 清除上下文数据*/public static void clearDbType() {contextHolder.remove();}
}
6、数据库枚举
package com.example.testtdengine.config.db;public enum DBTypeEnum {mysql("mysql"),tdengine("tdengine");private String value;DBTypeEnum(String value) {this.value = value;}public String getValue() {return value;}
}
7、封装动态切库
package com.example.testtdengine.config.db;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {protected Object determineCurrentLookupKey() {return DbContextHolder.getDbType();}
}
8、修改mybatis全局配置
package com.example.testtdengine.config.db;import com.baomidou.mybatisplus.core.config.GlobalConfig;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.PostConstruct;public class MyGlobalConfig extends GlobalConfig {@Autowiredprivate CustomSqlSessionTemplate sqlSessionTemplate;private static CustomSqlSessionTemplate customSqlSessionTemplate;@Overridepublic SqlSessionFactory getSqlSessionFactory() {return customSqlSessionTemplate.getSqlSessionFactory();}@PostConstructpublic void init() {MyGlobalConfig.customSqlSessionTemplate = sqlSessionTemplate;}
}
9、注入分页插件
package com.example.testtdengine.config;import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.example.testtdengine.config.db.DBTypeEnum;
import com.example.testtdengine.config.db.DynamicDataSource;
import com.example.testtdengine.config.interceptor.TaosDynamicTableNameInnerInterceptor;
import com.example.testtdengine.config.interceptor.TaosTableNameHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 动态表名插件TaosDynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new TaosDynamicTableNameInnerInterceptor();dynamicTableNameInnerInterceptor.setTableNameHandler(new TaosTableNameHandler());interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);return interceptor;}@Bean(name = "mysql")@ConfigurationProperties(prefix = "spring.datasource.druid.mysql")public DataSource mysql() {return DruidDataSourceBuilder.create().build();}@Bean(name = "tdengine")@ConfigurationProperties(prefix = "spring.datasource.druid.tdengine")public DataSource tdengine() {return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic DataSource multipleDataSource(@Qualifier("mysql") DataSource mysql,@Qualifier("tdengine") DataSource tdengine) {DynamicDataSource dynamicDataSource = new DynamicDataSource();Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DBTypeEnum.mysql.getValue(), mysql);targetDataSources.put(DBTypeEnum.tdengine.getValue(), tdengine);// 程序默认数据源,这个要根据程序调用数据源频次,经常把常调用的数据源作为默认dynamicDataSource.setDefaultTargetDataSource(tdengine);dynamicDataSource.setTargetDataSources(targetDataSources);return dynamicDataSource;}@Bean("sqlSessionFactory")public SqlSessionFactory sqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();sqlSessionFactory.setDataSource(multipleDataSource(mysql(), tdengine()));MybatisConfiguration configuration = new MybatisConfiguration();configuration.setJdbcTypeForNull(JdbcType.NULL);configuration.setMapUnderscoreToCamelCase(true);configuration.setCallSettersOnNulls(true);configuration.setCacheEnabled(false);GlobalConfig.DbConfig dab = new GlobalConfig.DbConfig();dab.setIdType(IdType.AUTO);sqlSessionFactory.setConfiguration(configuration);//添加分页功能sqlSessionFactory.setPlugins(new Interceptor[]{mybatisPlusInterceptor()});return sqlSessionFactory.getObject();}}
主要配置如下图所示
相关文章:

Java连接TDengine和MySQL双数据源
git文件地址:项目首页 - SpringBoot连接TDengine和MySQL双数据源:SpringBoot连接TDengine和MySQL双数据源 - GitCode 1、yml配置 spring:datasource:druid:mysql:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/testusername: roo…...

Web3 游戏周报(1.13 - 1.19)
回顾上周的区块链游戏概况,查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【1.13–1.19】Web3 游戏行业动态 索尼区块解决方案实验室 (Sony BSL) 宣布其以太坊 L2 区块链 Soneium 主网上线。Hyve Labs 融资 275 万美元,推动 Web3 游戏基础设…...

[深度学习]机器学习和深度学习
机器学习和深度学习 文章目录 机器学习和深度学习人工智能与机器学习和深度学习的关系侠义的机器学习深度学习的概念常见的神经网络的输入形式想要的输出(任务类别)深度学习的流程 线性函数与多层神经元 人工智能与机器学习和深度学习的关系 所谓人工智能就是,让计算…...
区块链技术
区块链是一个信息技术领域的术语,它代表了去中心化、安全性高、透明度强的分布式账本技术。以下是对区块链的详细介绍: 一、定义与基本原理 区块链(Blockchain)是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方案…...
vim函数定义跳转相关设置
修改下vim的一些ctags相关快捷键,个人用着顺手点。 小结如下: normal模式下的gk,用来打开一个预览窗口预览函数定义(需要ctags生成好tags文件)。normal模式下的gd,修改映射为ctrl],即跳转到函…...

如何使用Python爬虫获取微店商品详情:代码示例与实践指南
在电商领域,获取商品详情数据对于商家和开发者来说至关重要。微店作为国内知名的电商平台,提供了丰富的商品数据接口,方便开发者通过API调用获取商品详情。本文将详细介绍如何使用Python爬虫获取微店商品详情,并提供具体的代码示例…...

Autosar CP RTE规范解读之不同 BSW 接口的通知与软件组件激活机制:标准化接口与 AUTOSAR 接口的实现方式
在汽车电子系统开发中,特别是在遵循 AUTOSAR 架构的系统中,基本软件(BSW)模块之间的通信和信息通知机制至关重要,它直接影响着系统的性能、可靠性以及各个软件组件之间的协同工作能力。本文根据不同类型的 BSW 接口&am…...

基于STM32的智能门锁安防系统(开源)
目录 项目演示 项目概述 硬件组成: 功能实现 1. 开锁模式 1.1 按键密码开锁 1.2 门禁卡开锁 1.3 指纹开锁 2. 功能备注 3. 硬件模块工作流程 3.1 步进电机控制 3.2 蜂鸣器提示 3.3 OLED显示 3.4 指纹与卡片管理 项目源代码分析 1. 主程序流程 (main…...
搭建Hadoop源代码阅读环境
个人博客地址:搭建Hadoop源代码阅读环境 | 一张假钞的真实世界 环境 Mac OS X EI Capitan 10.11.6java version “1.7.0_80”git version 2.7.4 (Apple Git-66)Apache Maven 3.3.9下载源代码 从Git上下载最新源代码: git clone git://git.apache.org/hadoop-common.git 构…...

【25】Word:林涵-科普文章❗
目录 题目 NO1.2.3 NO4.5.6 NO7.8 NO9.10 NO11.12 不连续选择:按住ctrl按键,不连续选择连续选择:按住shift按键,选择第一个,选择最后一个。中间部分全部被选择 题目 NO1.2.3 布局→纸张方向:横向…...
Spring Boot接收参数的19种方式
Spring Boot是一个强大的框架,允许开发人员通过多种方式接收和处理参数。无论是HTTP请求参数、路径变量,还是请求体中的数据,Spring Boot都能提供灵活的处理方式。本文将介绍19种不同的方式来接收参数。 1. 查询参数(Query Param…...

云IDE:开启软件开发的未来篇章
敖行客一直致力于将整个研发协作流程线上化,从而打破物理环境依赖,让研发组织模式更加灵活、自由且高效,今天就来聊聊AT Work(一站式研发协作平台)的重要组成部分-云IDE。 在科技领域,历史常常是未来的风向…...
Leetcode 189 轮转数组
leetcode 189 轮转数组 题目 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向…...

华为服务器(iBMC)监控指标解读
美信监控易内置了数千种常见设备监测器,能够监测超过20万项指标。这些指标涵盖了从硬件设备到软件系统,从网络性能到安全状态等各个方面。如下基于美信监控易——IT基础监控模块,对华为服务器(iBMC)部分监控指标进行解…...

网络编程-UDP套接字
文章目录 UDP/TCP协议简介两种协议的联系与区别Socket是什么 UDP的SocketAPIDatagramSocketDatagramPacket 使用UDP模拟通信服务器端客户端测试 完整测试代码 UDP/TCP协议简介 两种协议的联系与区别 TCP和UDP其实是传输层的两个协议的内容, 差别非常大, 对于我们的Java来说, …...

Web 音视频(一)基础知识
前言 阅读后续文章或开始使用 WebAV 处理音视频数据之前,需要一点点背景知识。 本篇主要简单介绍音视频最基础的知识,以及 WebCodecs 的核心 API。 视频结构 视频文件可以理解为容器包含了元数据和编码数据(压缩的音频或视频)…...

数字化时代,传统代理模式的变革之路
在数字化飞速发展的今天,线上线下融合(O2O)成了商业领域的大趋势。这股潮流,正猛烈冲击着传统代理模式,给它带来了新的改变。 咱们先看看线上线下融合现在啥情况。线上渠道那是越来越多,企业纷纷在电商平台…...

Linux 高级路由与流量控制-用 tc qdisc 管理 Linux 网络带宽
大家读完记得觉得有帮助记得关注和点赞!!! 此分享内容比较专业,很多与硬件和通讯规则及队列,比较底层需要有技术功底人员深入解读。 Linux 的带宽管理能力 足以媲美许多高端、专用的带宽管理系统。 1 队列࿰…...
【数据库知识】PostgreSQL介绍
PostgreSQL介绍 概述一、起源与发展二、特性与功能三、PL/pgSQL语言四、应用场景五、配置与优化 核心概念一、基础数据结构二、数据操作三、高级特性四、应用场景 多版本控制MVCC说明一、MVCC的基本概念二、MVCC的实现原理三、MVCC的工作流程四、MVCC的优势五、MVCC的局限性 可…...

软考,沟通管理
软件沟通管理 已发送、巳收到、已理解、己认可、已转化为积极的行动 有效的沟通活动和成果创建具有如下3个基本属性:①沟通目的明确;②尽量了解沟通接收方,满足其需求及偏好;③监督并衡量沟通的效果。 让干系人参加项目会议&…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...