一篇搞懂springboot多数据源
好文推荐
- https://zhuanlan.zhihu.com/p/563949762
mybatis 配置多数据源
参考文章
- https://blog.csdn.net/qq_38353700/article/details/118583828
使用mybatis配置多数据源我接触过的有两种方式,一种是通过java config的方式手动配置两个数据源,另一种方式便是使用mybatis-plus-dynamic。*
总体来说,配置主要包括,产生DataSource,然后是mybatis所需要的SqlSessionFactory,以及配置相应的事务管理器
示例代码
-
pom
<!--MyBatis整合SpringBoot框架的起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!-- Mysql驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version></dependency><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.8</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
-
配置文件 yml
server:port: 8080spring:datasource:master:jdbc-url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverslave:jdbc-url: jdbc:mysql://43.143.217.124:3306/hongbei?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
-
java config 配置数据源一
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;/*** @Classname DB1DataSourceConfig* @Description DB1DataSourceConfig* @Date 2023-02-24 15:14* @Created by lihw*/ @Configuration @MapperScan(basePackages = "com.example.demo.mapper.master",sqlSessionFactoryRef = "masterSqlSessionFactory") public class DB1DataSourceConfig {String MAPPER_LOCATION = "classpath*:abc/*.xml";@Primary@Bean("masterDataSource")@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource getMasterDataSource() {return DataSourceBuilder.create().build();}@Primary@Bean("masterSqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {// 使用 mybatis plus 配置//MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();//mybatisSqlSessionFactoryBean.setDataSource(dataSource);//mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()// .getResources(MAPPER_LOCATION)); // "classpath:mapping/*Mapper.xml"//mybatisSqlSessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity");////return mybatisSqlSessionFactoryBean.getObject();// mybatis 配置SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));sqlSessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity.master");org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();configuration.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(configuration);return sqlSessionFactoryBean.getObject();}@Primary@Bean("masterSqlSessionTemplate")public SqlSessionTemplate sqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);return sqlSessionTemplate;}@Bean("masterTransactionManager")public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);return dataSourceTransactionManager;}}
-
配置数据源 二
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;/*** @Classname DB1DataSourceConfig* @Description DB1DataSourceConfig* @Date 2023-02-24 15:14* @Created by lihw*/ @Configuration @MapperScan(basePackages = "com.example.demo.mapper.slave",sqlSessionFactoryRef = "slaveSqlSessionFactory") public class DB2DataSourceConfig {String MAPPER_LOCATION = "classpath*:slave/*.xml";//@Primary@Bean("slaveDataSource")@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource getSlaveDataSource() {return DataSourceBuilder.create().build();}//@Primary@Bean("slaveSqlSessionFactory")public SqlSessionFactory sqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {// mybatis plus配置//MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();//mybatisSqlSessionFactoryBean.setDataSource(dataSource);//mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()// .getResources(MAPPER_LOCATION)); // "classpath:mapping/*Mapper.xml"//mybatisSqlSessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity");////return mybatisSqlSessionFactoryBean.getObject();// mybatis 配置SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));sqlSessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity.slave");// 设置mybatis配置org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();// 下划线转驼峰configuration.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(configuration);return sqlSessionFactoryBean.getObject();}//@Primary@Bean("slaveSqlSessionTemplate")public SqlSessionTemplate sqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);return sqlSessionTemplate;}@Bean("slaveTransactionManager")public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);return dataSourceTransactionManager;}}
-
目录结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K95yKTJe-1677467535741)(https://note.youdao.com/yws/res/4010/WEBRESOURCE3a7424410d156d5dc0d6bd00cd7bf638 “image.png”)]
-
测试接口
@RestController @RequestMapping("/test") public class TestController {@AutowiredStudentMapper studentMapper;@AutowiredSysUserMapper sysUserMapper;// 数据源一 查询@GetMapping("list")public List<Student> getUserList(){List<Student> userList = studentMapper.getUserList();System.out.println(userList);return userList;}// 数据源二 查询@GetMapping("msg2")public String getmsg2(){List<SysUser> user = sysUserMapper.getUserList();System.out.println(user);return "msg22";}}
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZSCJmOj9-1677467535743)(https://note.youdao.com/yws/res/4016/WEBRESOURCE0cc80d06ca0c483d00bb9e34f16ef10d)]
使用 mybatis-plus-dynamic 配置多数据源
-
pom
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.1</version> </dependency>
-
yml
# mybatis-plus-dynamic 配置多数据源 spring:datasource:dynamic:datasource:master:url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://43.143.217.124:3306/hongbei?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# 指定主数据库primary: master#mybatis: # mapper-locations: classpath*:abc/*.xml,classpath*:slave/*.xmlmybatis-plus:mapper-locations: classpath*:abc/*.xml,classpath*:slave/*.xml
-
使用案例
@Service @DS("slave-1") public class TbServiceImpl extends ServiceImpl<TbDao, TbBean> implements TbService {@Overridepublic String save1() {TbBean tbBean = new TbBean();tbBean.setName("王五");tbBean.setSubject("英语");tbBean.setScore(113);this.save(tbBean);return "success";} }
此处是模拟的一个新增操作,注意类上面的@DS注解,该注解可以标注在类或方法上面;也可以标注在Mapper接口上面,但是不建议同时在Mapper和service上同时标注,可能会出现问题。该注解的value属性便是对应于在yaml中配置的数据源名称,如果没有给值,默认就是使用数据源名为master的数据源。
- 踩坑日记:
如下代码:
@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl<UserDao, UserBean> implements UserService {@Autowiredprivate TbService tbService;@Override@Transactional(rollbackFor = Exception.class)public void add() {UserBean userBean = new UserBean();userBean.setId(3);userBean.setLoginName("zhangsan");userBean.setName("张三");userBean.setPassword("123456");this.save(userBean);// 第二个数据源tbService.save1();}
}
意思就是我想在保存userBean时同时调用一下tbService的save1方法,注意tbService被@DS(“slave-1”)注解标注,它对应于sqlServer数据库的操作。当直接调用上面的add方法时,会报如下的错误:
反正就是死活找不到tb这张表,实际上tb这张表是确实存在于sqlServer数据库中的,之所以报错是由于加事务的原因@Transactional(rollbackFor = Exception.class),由于spring事务默认的传播级别是:
Propagation.REQUIRED
这个事务的特性就是如果上级方法调用时已经获取了事务,则该方法内调用的其它事务方法将复用同一个事务,结果就是对userBean的操作是对应于mysql的,由于加了事务,所以tbService.save1()方法还是在该事务内,造成的结果就是会在mysql数据库中找tb这张表,肯定找不到,结果就报错了,解决方式如下:
@Service
@DS("slave-1")
public class TbServiceImpl extends ServiceImpl<TbDao, TbBean> implements TbService {@Override@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)public String save1() {TbBean tbBean = new TbBean();tbBean.setName("王五");tbBean.setSubject("英语");tbBean.setScore(113);this.save(tbBean);return "success";}
}
给save1()方法加上 @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) , 使其在每次获取事务时都是重新产生一个,不再复用上级方法的事务。
druid + mybatis 所数据源配置
-
pom
<!-- Druid 数据连接池依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency><!--MyBatis整合SpringBoot框架的起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><!-- jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.8</version></dependency><!-- Mysql驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version></dependency>
-
yml
# druid 多数据源配置 master:datasource:url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverslave:datasource:url: jdbc:mysql://43.143.217.124:3306/hongbei?characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
-
数据源一 配置
import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;/*** @Classname DruidConfig* @Description DruidConfig* @Date 2023-02-27 10:45* @Created by lihw*/ @Configuration @MapperScan(basePackages = {DruidConfig.PACKAGE},sqlSessionFactoryRef = "masterSqlSessionFactory") public class DruidConfig {// 精确到 master 目录,以便跟其他数据源隔离static final String PACKAGE = "com.example.demo.mapper.master";static final String MAPPER_LOCATION = "classpath:abc/**/*.xml";@Value("${master.datasource.url}")private String url;@Value("${master.datasource.username}")private String user;@Value("${master.datasource.password}")private String password;@Value("${master.datasource.driver-class-name}")private String driverClass;@Bean("masterDataSource")@Primarypublic DataSource masterDataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClass);druidDataSource.setUrl(url);druidDataSource.setUsername(user);druidDataSource.setPassword(password);return druidDataSource;}@Bean("masterTransactionManager")@Primarypublic DataSourceTransactionManager masterTransactionManager(){return new DataSourceTransactionManager(masterDataSource());}@Bean("masterSqlSessionFactory")@Primarypublic SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));// mybatis 配置org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();// 驼峰下划线configuration.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(configuration);return sqlSessionFactoryBean.getObject();}}
-
数据源二 配置
import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource;/*** @Classname DruidConfig* @Description DruidConfig* @Date 2023-02-27 10:45* @Created by lihw*/ @Configuration @MapperScan(basePackages = {DruidConfig2.PACKAGE},sqlSessionFactoryRef = "slaveSqlSessionFactory") public class DruidConfig2 {// 精确到 master 目录,以便跟其他数据源隔离static final String PACKAGE = "com.example.demo.mapper.slave";static final String MAPPER_LOCATION = "classpath:slave/**/*.xml";@Value("${slave.datasource.url}")private String url;@Value("${slave.datasource.username}")private String user;@Value("${slave.datasource.password}")private String password;@Value("${slave.datasource.driver-class-name}")private String driverClass;@Bean("slaveDataSource")@Primarypublic DataSource slaveDataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClass);druidDataSource.setUrl(url);druidDataSource.setUsername(user);druidDataSource.setPassword(password);return druidDataSource;}@Bean("slaveTransactionManager")@Primarypublic DataSourceTransactionManager slaveTransactionManager(){return new DataSourceTransactionManager(slaveDataSource());}@Bean("slaveSqlSessionFactory")@Primarypublic SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));// mybatis 配置org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();// 驼峰下划线configuration.setMapUnderscoreToCamelCase(true);sqlSessionFactoryBean.setConfiguration(configuration);return sqlSessionFactoryBean.getObject();}}
-
测试代码
@RestController @RequestMapping("/test") public class TestController {@AutowiredStudentMapper studentMapper;@AutowiredSysUserMapper sysUserMapper;@GetMapping("list")public List<Student> getUserList(){List<Student> userList = studentMapper.getUserList();System.out.println(userList);return userList;}@GetMapping("msg2")public String getmsg2(){List<SysUser> user = sysUserMapper.getUserList();System.out.println(user);return "msg22";}}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnOmBExy-1677467535745)(https://note.youdao.com/yws/res/4051/WEBRESOURCE1a8c5b356140fb73fc973a659243a302)]
相关文章:

一篇搞懂springboot多数据源
好文推荐 https://zhuanlan.zhihu.com/p/563949762 mybatis 配置多数据源 参考文章 https://blog.csdn.net/qq_38353700/article/details/118583828 使用mybatis配置多数据源我接触过的有两种方式,一种是通过java config的方式手动配置两个数据源,…...

Verilog 数据类型和数组简介
在这篇文章将讨论 verilog 中最常用的数据类型,包括对数据表示,线网类型、变量类型,向量类型和数组的讨论。尽管 verilog 被认为是一种弱类型语言(loosely typed),但设计者仍必须在 Verilog 设计中为每个端…...

【数据结构】时间复杂度和空间复杂度以及相关OJ题的详解分析
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录1.算法效率1.1 如何衡…...
31--Vue-前端开发-Vue语法
一、前端-Vue介绍 1.前端介绍 1、HTML(5)、CSS(3)、JavaScript(ES5、ES6):编写一个个的页面 ----> 给后端(PHP、Python、Go、Java) ----> 后端嵌入模板语法 ----> 后端渲染完数据 ----> 返回数据给前端 ----> 在浏览器中查看 2、Ajax的出现 -> 后台发送异…...
这份IC设计必读书单,值得所有IC设计工程师一看!
《综合与时序分析的设计约束》 作者:Sridhar Gangadharan 本书为集成电路时序约束设计的指南,指导读者通过指定的时序要求,充分发挥IC设计的性能。本书内容包括受时序约束的关键环节的设计流程、综合时序分析、静态时序分析和布局布线等。本书…...

Acwing 蓝桥杯 第一章 递归与递推
我上周在干什么,感觉我上周啥也没训,本来两天一次的vp也没v很寄啊,再这样下去真不行了先总结一下如何爆搜:先去确定好枚举的对象枚举的对象很重要!!这直接影响了复杂度然后就是去想递归树就好了一、确定状态…...

模型部署笔记
目录模型部署工作ONNX存在的意义ONNX(Open Neural Network Exchange)ONNX示例模型推理示例Batch调整量化量化方式常见问题模型部署工作 训练好的模型在特定软硬件平台下推理针对硬件优化和加速的推理代码 训练设备平台: CPU、GPU、DSP ONN…...

多线程之wait和notify
目录 1.wait()方法 2. notify方法 因为线程之间是抢占式执行的,所以线程之间执行的先后顺序难以预知。但是实际开发中,我们希望线程之间的执行顺序是能被掌控的,比如线程2开始之前,需要线程1的某个任务先被执行。也就是说,很多时…...

MVCC 当前读 快照读 RC read view RR下事务更新不会丢失
MVCC(multi-version-concurrent-control) MVCC是行锁的一个变种,但MVCC在很多情况下它避免了加锁。不是buffer块,而是buffer中的记录行。 MVCC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制&#x…...

NCRE计算机等级考试Python真题(二)
第二套试题1、关于算法的描述,以下选项中错误的是A.算法具有可行性、确定性、有穷性的基本特征B.算法的复杂度主要包括时间复杂度和数据复杂度C.算法的基本要素包括数据对象的运算和操作及算法的控制结构D.算法是指解题方案的准确而完整的描述正确答案: …...
借助IBM Spectrum LSF为芯片行业大幅提升算力,预测未来
IBM Spectrum LSF 客户案例——上海开赟软件服务有限公司借助IBM Spectrum LSF为芯片行业大幅提升算力,预测未来 业务影响 中国芯片市场作为全球消费芯片市场重要组成部分,近年来发展迅猛。据国家统计局统计,2019年中国集成电路产量突破200…...

力扣-换座位
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:626. 换座位二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言 …...

DFT基本入门介绍
1.什么是DFT?2.为什么要做DFT?3.“测试”与“验证”的区别4.DFT的核心技术1)扫描路径设计(Scan Design)2)内建自测试(Bist)3)JTAG4)ATPG5.DFT工程师的岗位职责随着芯片的制程越来小(5nm), 芯片的规模越来越…...

做「增长」必须懂的6大关键指标
无论你所从事的是哪个行业,增长都不是一件易事,SaaS公司想要维持长期的增长更是难上加难。这是因为SaaS公司对未来回报的依赖程度更大,反观那些传统商业模式的公司,主要的收入来源都集中在产品购买交付的时点上,而客户…...
Linux:soft lockup 检测机制
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 分析背景 本文分析基于 linux-4.14.132 内核代码分析,运行环境 Ubuntu 16.04.4 LTS QEMU ARM vexpress-a9 ,rootfs 基…...
天线理论知识4——非频变天线
目录 简介自补结构巴比涅原理天线的描述常见的非频变天线简介 所谓的非频变天线指的是天线的参数几乎不随着频率的改变而发生变化。 自补结构 天线的自补结构指的是:由无限大且无厚度的理想导电区域的自由空间中的非导电区域放置一起的结构称为自补结构。包含金属部分和非金…...
基础架构组件选型及服务化
常见的分布式基础架构组件 分布式服务化框架,业界开源产品比如 Dubbo、Spring Cloud 这样的框架;分布式缓存及框架,业界如 Redis、Memcached,框架如 Codis 和 Redis Cluster;数据库及分布式数据库框架,这两…...

leetcode-每日一题-1247(中等,数学逻辑)
这道题当理解清了意思之后,只要是s1和s2的某位置的字母一样时我们就可以忽视比如s1"xxxxxxyyyy"; 就可以看成s1"xxxyyyy";s2"xxxyyyxxxx"; s2"yyyxxxx";其次就是只有当x和y位置差异产生的数量同奇偶的时候才可以构成相等字…...

前端面试题 —— 计算机网络(一)
目录 一、常见的HTTP请求头和响应头 二、HTTP状态码304是多好还是少好? 三、OPTIONS请求方法及使用场景 四、对keep-alive的理解 五、HTTP协议的优点和缺点 六、URL有哪些组成部分? 七、HTTPS通信(握手)过程 八、HTTPS的特…...

分布式-分布式缓存笔记
分布式系统缓存 缓存分类 前端缓存 前端缓存包括页面和浏览器缓存,如果是 App,那么在 App 端也会有缓存。当你打开商品详情页,除了首次打开以外,后面重复刷新时,页面上加载的信息来自多种缓存。 页面缓存属于客户端…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...

PydanticAI快速入门示例
参考链接:https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...