当前位置: 首页 > news >正文

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文件地址&#xff1a;项目首页 - 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)

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

[深度学习]机器学习和深度学习

机器学习和深度学习 文章目录 机器学习和深度学习人工智能与机器学习和深度学习的关系侠义的机器学习深度学习的概念常见的神经网络的输入形式想要的输出(任务类别)深度学习的流程 线性函数与多层神经元 人工智能与机器学习和深度学习的关系 所谓人工智能就是&#xff0c;让计算…...

区块链技术

区块链是一个信息技术领域的术语&#xff0c;它代表了去中心化、安全性高、透明度强的分布式账本技术。以下是对区块链的详细介绍&#xff1a; 一、定义与基本原理 区块链&#xff08;Blockchain&#xff09;是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方案…...

vim函数定义跳转相关设置

修改下vim的一些ctags相关快捷键&#xff0c;个人用着顺手点。 小结如下&#xff1a; normal模式下的gk&#xff0c;用来打开一个预览窗口预览函数定义&#xff08;需要ctags生成好tags文件&#xff09;。normal模式下的gd&#xff0c;修改映射为ctrl]&#xff0c;即跳转到函…...

如何使用Python爬虫获取微店商品详情:代码示例与实践指南

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

Autosar CP RTE规范解读之不同 BSW 接口的通知与软件组件激活机制:标准化接口与 AUTOSAR 接口的实现方式

在汽车电子系统开发中&#xff0c;特别是在遵循 AUTOSAR 架构的系统中&#xff0c;基本软件&#xff08;BSW&#xff09;模块之间的通信和信息通知机制至关重要&#xff0c;它直接影响着系统的性能、可靠性以及各个软件组件之间的协同工作能力。本文根据不同类型的 BSW 接口&am…...

基于STM32的智能门锁安防系统(开源)

目录 项目演示 项目概述 硬件组成&#xff1a; 功能实现 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 不连续选择&#xff1a;按住ctrl按键&#xff0c;不连续选择连续选择&#xff1a;按住shift按键&#xff0c;选择第一个&#xff0c;选择最后一个。中间部分全部被选择 题目 NO1.2.3 布局→纸张方向&#xff1a;横向…...

Spring Boot接收参数的19种方式

Spring Boot是一个强大的框架&#xff0c;允许开发人员通过多种方式接收和处理参数。无论是HTTP请求参数、路径变量&#xff0c;还是请求体中的数据&#xff0c;Spring Boot都能提供灵活的处理方式。本文将介绍19种不同的方式来接收参数。 1. 查询参数&#xff08;Query Param…...

云IDE:开启软件开发的未来篇章

敖行客一直致力于将整个研发协作流程线上化&#xff0c;从而打破物理环境依赖&#xff0c;让研发组织模式更加灵活、自由且高效&#xff0c;今天就来聊聊AT Work&#xff08;一站式研发协作平台&#xff09;的重要组成部分-云IDE。 在科技领域&#xff0c;历史常常是未来的风向…...

Leetcode 189 轮转数组

leetcode 189 轮转数组 题目 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 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)监控指标解读

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

网络编程-UDP套接字

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

Web 音视频(一)基础知识

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

数字化时代,传统代理模式的变革之路

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

Linux 高级路由与流量控制-用 tc qdisc 管理 Linux 网络带宽

大家读完记得觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 此分享内容比较专业&#xff0c;很多与硬件和通讯规则及队列&#xff0c;比较底层需要有技术功底人员深入解读。 Linux 的带宽管理能力 足以媲美许多高端、专用的带宽管理系统。 1 队列&#xff0…...

【数据库知识】PostgreSQL介绍

PostgreSQL介绍 概述一、起源与发展二、特性与功能三、PL/pgSQL语言四、应用场景五、配置与优化 核心概念一、基础数据结构二、数据操作三、高级特性四、应用场景 多版本控制MVCC说明一、MVCC的基本概念二、MVCC的实现原理三、MVCC的工作流程四、MVCC的优势五、MVCC的局限性 可…...

软考,沟通管理

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

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...