一篇搞懂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 端也会有缓存。当你打开商品详情页,除了首次打开以外,后面重复刷新时,页面上加载的信息来自多种缓存。 页面缓存属于客户端…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...