MyBatis-Plus 自定义 COUNT 查询 有更新! 2023-08-14 前言 在使用 MyBatis-Plus 的分页组件进行分页查询时, MyBatis-Plus 会自动帮我们返回总数、当前页、总页数等参数,总数是 MyBatis-Plus 自己使用我们的数据查询 SQL 外面套了一层查询来返回总数,虽然 MyBatis-Plus 官方也说明了这里有优化,但是需要根据标准走,若没有根据标准来或者 SQL 比较复杂等特殊情况,还是无法避免会被直接套在外面导致查询效率低下,我这里的情况是由于原分页查询的逻辑较复杂,原先为两个 OR,后改为两个 UNION ALL,COUNT 查询套在 UNION ALL 查询里,竟然比数据查询耗时都要长,所需需要特殊处理一下 COUNT 查询; 官方解释:https://baomidou.com/pages/97710a/#page 查询优化 本次优化的 COUNT 查询中,摒弃了 MyBatis-Plus 默认套的查询,采用自己写一个新 SQL 的方式来代替,在多次试验中,最终的 SQL 和原查询数据的 SQL 大致相同,还是两次 UNION ALL 来查询,但是字段只返回 COUNT 数量且无需 LEFT JOIN....
Hippo4j动态线程池监控接入 有更新! 2023-07-25 简单了解 线程池痛点 原文摘录 线程池是一张基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。 如果有在项目中实际使用线程池,相信你可能会遇到一下痛点 线程池随便定义,线程资源过多,造成服务器高负载; 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险; 线程池任务执行时间超过平均时间,开发人员无法感知; 线程池任务堆积,触发拒绝策略,影响既有业务正常运行; 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起; 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GC。 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃; 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手; 如果同学们有以上的问题或者疑问,接着往下看。 什么是 Hippo4j 原文摘录 Hippo4j 通过对 JDK 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力。 提供一下功能支持 全局管控 ....
日常开发之git小技巧-01(git stash系列) 2023-03-06 前言 日常开发中,经常会有好几个需求状态不同但是同时在进行的情况,比如目前有一到两个提测的需求,一个开发中的需求,此时提测中的需求有 bug 需要现在处理,或者正在开发新需求的同时,线上出现问题需要切换分支,但是我们此时开发中的需求上的代码还没写完,有一些测试代码或者并不想提交到开发分支中,这是可以用到我们的 git stash 系列命令 功能介绍 官方解释:当您想记录工作目录和索引的当前状态,但又想返回一个干净的工作目录时,请使用 git stash。该命令将保存本地修改,并恢复工作目录以匹配头部提交。 stash 命令能够将还未 commit 的代码存起来,让你的工作目录变得干净。 大概就是把当前修改的代码暂存起来,暂存并不是 add 或者 commit,不会有提交记录,不会提交到本地仓库; 功能详解 git stash 保存当前的工作区与暂存区的状态,把当前的修改的保存到 git 栈,等以后需要的时候再恢复,git stash 这个命令可以多次使用,每次使用都会新加一个 stash@{num},num 是编号 git stash save '注释' 作⽤等同于 gi....
Charles抓包App,数据迁移过程 有更新! 2023-01-15 前言 博主从 2022 年 1 月 1 日开始使用 App Store 中的一个免费软件开始记账,就叫 A 记账软件吧,在前一段时间的某一天,发现 A 记账软件中的图片显示异常,还不觉得有什么,能记账就行了,直到 2023 年 1 月 9 日晚上下班到家后,照常打开记账软件,发现不仅图片不显示,记账功能还挂了,如下图所示 紧接着就去找这个软件有没有账单导出的功能,找了一圈后,很遗憾,并没有此功能,一想到自己辛辛苦苦记了一年的账,一天都没落下,又害怕昨天图片没了, 今天记不了账了,万一明天连查询功能都不行的话,那就真完蛋了,一年白记。 于是一拍大腿想了个办法,既然它没有导出的功能,那我自己爬出来不就行了,我自己爬我自己的数据总可以吧! 最开始先搜了一圈爬手机 APP 的软件和方法,后来干脆直接问公司的测试同事,同事说可以使用 Charles 爬取,还贴心的给了个 pdf 的教程,万分感谢! 也就有了下面的故事 前期准备 首先博主的电脑和手机都是苹果系统,windowns 的大家能从本文中用到的方法就用,用不到我也没办法哈 一、软件下载&安装 进入 Charles 官网下载软....
ElasticSearch 解除默认查询1w数据限制 2023-01-03 默认查询 1GET seller_invoice_item_wide_data_test/_search 2{ 3 "size": 0 4} 查询结果 1{ 2 "took" : 1, 3 "timed_out" : false, 4 "_shards" : { 5 "total" : 1, 6 "successful" : 1, 7 "skipped" : 0, 8 "failed" : 0 9 }, 10 "hits" : { 11 "total" : { 12 "value" : 10000, 13 "relation" : "gte" 14 }, 15 "max_score" : null, 16 "hits" : [ ] 17 } 18} 19 解除默认 1w 限制 1GET seller_invoice_item_wide_data_test/_search 2{ 3 "size": 0, 4 "track_total_hits": true 5} 查询结果 1{ 2 "took" : 1, 3 "timed_out" : false, 4 ....
Mac下载安装ElasticSearch 有更新! 2022-12-13 一、下载 ElasticSearch 官网下载对应版本(https://www.elastic.co/cn/downloads/past-releases#elasticsearch) 解压下载的压缩包 tar -zxvf elasticsearch-7.6.1-darwin-x86_64.tar.gz bin 目录下运行 elasticsearch 启动成功 访问 二、下载 Kibana 下载可视化工具 Kibana(https://www.elastic.co/cn/downloads/past-releases#kibana) 解压下载的压缩包 tar -zxvf kibana-7.6.1-darwin-x86_64.tar.gz 启动 Kibana,bin 目录下运行 Kibana 启动成功 访问 Kibana 中文设置,进入 config 目录,输入 vim kibana.yml ,将最后一行配置放开并且更改为 zh-CN,重启 Kibana 即可 三、下载 ElasticSearch....
CompletableFuture 有更新! 2022-11-30 一、前言 Java 支持的多线程开启方式 根据 Oracle 官方出具的 Java 文档说明,创建线程的方式只有两种:继承 Thread 或者实现 Runnable 接口。但是这两种方法都存在一个缺陷,没有返回值,也就是说我们无法得知线程执行结果。虽然简单场景下已经满足,但是当我们需要返回值的时候怎么办呢?Java1.5 以后得 Callable 和 Future 接口就解决了这个问题,我们可以通过向线程池提交一个 Callable 来获取一个包含返回值的 Future 对象,从此,我们的程序逻辑就不再是同步顺序。 下面是 Java8 实战书籍的原文: 1Future接口在Java5中被引入,设计初衷是对将来某个时刻会产生的结果进行建模。它建模了一种异步运算,返回了一个执行结果的引用,当运算结束后,这个引用被返回给调用方。在Future中触发那些潜在耗时的操作完成,我们从最初的串行操作变成了并行,在异步的同时,我们还可以做其他事情来解决程序运行时间。 Future 接口的局限性 当我们得到包含结果的 Future 时,我们可以使用 get()方法等待线程完成并获取返回值,但是 Fut....
ParallelStream 并行流 有更新! 2022-11-25 一、什么是流 Stream 是 Java8 中新增加的一个特性,统称为流,它不是数据结构也不存放任何数据,其主要用于集合的逻辑处理。 二、Stream 和 Iterator 的区别 Iterator 作为迭代器,其按照一定的顺序迭代遍历集合中的每一个元素,并且对每个元素进行指定的操作。而 Stream 在此基础上还可以将这种操作并行化,利用多核处理器的优势快速处理集合(集合的数据会分成多个段,有多个线程处理)。 三、Stream 的使用 Stream 完全依赖于接口化编程方式,以下举例了解下 Stream 的使用。 1 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); 2 numbers.stream().forEach(System.out::print); 3 // 输出12345678 由以上的例子可以看出,Stream 的遍历方式和结果与 Iterator 没什么差别,这是因为 Stream 的默认遍历和迭代器是相同的,保证以往使用迭代器的地方可以方便的改写为 Stream。 Stream....
Redis Redisson 发布/订阅模式 实现 2022-11-24 一、Redis 的发布订阅模式 什么是发布订阅 任务队列:顾名思义,就是"传递消息的队列"。与任务队列进行交互的实体有两类,一类是生产者(producer),另一类则是消费者(consumer)。生产者将需要处理的任务放入任务队列中,而消费者则不断地从任务队列中读取任务信息并执行。 发布订阅模式 其实从 Pub/Sub 的机制来看,它更像是一个广播系统,多个订阅者(Subscribe)可以订阅多个频道(Channel),多个发布者(Publisher)可以往多个频道(Channel)中发布消息。 可以这么简单的理解 Subscribe:收音机,可以收到多个频道,并以队列方式显示; Publisher:电台,可以往不同的 FM 频道中发消息; Channel:不同频率的 FM 频道; 特点 发送者(发布者)不是计划发送消息给特定的接受者(订阅者),而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅; 订阅者对一个或多个频道感兴趣,只需接受感兴趣的消息,不需要知道什么样的发布者发布的; 业务场景 说一个目前已经遇到的场景,客户端通过 websocket 和服务器进行长连....
分享一个bug Unsatisfied dependency expressed through field || Injection of resource dependencies failed 2022-07-21 一、事故发生时 项目中使用的腾讯云的 Apache Pulsar 消息中间件,对应的需求需要使用的延迟队列技术进行开发,所以创建了一个新的 topic 和 groupName,topicRef 和 groupName 都为 “commerce-red-apply-download”; 在开发完成后,构建项目时,报错上述标题错误,我们是分环境部署的,同样的代码,同样的 topicRef 和 groupName,在 dev 环境中可以构建启动成功,而在另一个环境则启动失败,报错上述标题错误,百思不得其解,说什么未满足依赖关系和注入资源依赖项失败; 最开始将问题定位到了 Bean 加载上面,想着既然这个类在加载的时候注入不进去其余的类,那我将这个类延迟加载,所以就把这个类加了个懒加载,行,这个类不报了,另外的类也开始报错这个,反复三四次之后,觉得不对劲,为什么之前都好好的类,现在都报这个错呢?这么无休止的加懒加载,也不太行,问题的根本就不在这个 Bean 的加载顺序上; 在面向百度编程了一会,依然没有得到想要的结果,就去仔细看报错日志,觉得是不是漏掉了什么?不看不知道,一看吓一跳,它隐藏的....
SpringBoot ContextLoaderListener、Servlet 有更新! 2022-05-08 一、问题 SpringBoot v2.3.2 中使用 ContextLoaderListener.getCurrentWebApplicationContext() 获取 WebApplicationContext 为空 二、原因 要使用这个 API 我们首先得明确它是个什么玩意儿,ContextLoaderListener 实际上就是一个监听器,作用就是启动 Web 容器时,自动装配 ApplicationContext 的配置信息,它实现了 ServletContextListener(三大生命周期监听之一); 摘个图 Spring 实现了 Tomcat 提供的 ServletContextListener 接口,写了一个监听器来监听项目启动,一旦项目启动,会触发 ContextLoaderListener 中的特定方法 contextInitialized 也就是说 Tomcat 的 ServletContext 创建时,会调用 ContextLoaderListener 的 contextInitialized(),这个方法内部的 initWebApplicationCon....
Git Revert Revert! 2022-05-02 一、前言 最近在工作中遇到个很有趣,让人费解的一个操作,举例子说明。 有两个分支,一个分支 A,一个分支 B,他们两个要合并在一起后,跟分支 C 合并,一通操作下来合并好之后,在 commit 记录中也可以看到两个分支的提交,然后提测,被告知分支 A 的功能没有实现,当时很费解,最后排查下来,发现在提测分支 C 中,没有分支 A 的代码,且无论你怎么 merge 分支 A,永远都是无任何修改。 当时有点不明所以,接着排查,发现在提测分支 C 中,有个操作为 Revery 分支 A 的提交记录,会不会和这个有关呢?将这个现象告知公司大佬后,由于时间比较紧张且分支 A 的代码没有多少,就手动将分支 A 的代码 copy 到了提测分支 C 中让测试人员继续。 之后在公司大佬研究后给出了个答案,大概问题出现原因为,提测分支 C 中的 Git 提交线只要存在针对于某次 merge 的 revert 操作,就会一直忽略掉这个 merge 里包含的提交内容。 如果对这句话不太了解的话,咱们用通俗的话来讲就是,你撤回了这个分支上的某次提交,Git 就会认为你不需要这一段代码,所以你想要把代码在合并上....
Junit4 单元测试注入bean失败 2022-04-22 一、报错截图 二、单元测试截图 三、解决 @SpringBootTest(classes = XxxApplication.class) 改为 @SpringBootTest(classes = XxxApplication.class, webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
分布式任务调度平台XXL-JOB 2022-03-02 一、下载源码 GitHub 地址:https://github.com/xuxueli/xxl-job/releases gitee 地址:http://gitee.com/xuxueli0323/xxl-job/releases 文档地址:https://www.xuxueli.com/xxl-job/ 二、初始化“调度数据库” 三、运行 xxl-job-admin 先修改 properties 文件中的数据库密码,改成自己的。 运行 四、打开管理后台 网址输入 http://localhost:8080/xxl-job-admin/ 五、创建执行器 六、创建任务 七、项目中使用 pom.xml 添加依赖 1 <!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --> 2 <dependency> 3 <groupId>com.xuxueli</groupId> 4 <artifactId>xxl-job-core</ar....
Spring Retry && Guava Retry 有更新! 2022-02-26 Spring Retry 一、引入 Maven 依赖 1 <!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry --> 2 <dependency> 3 <groupId>org.springframework.retry</groupId> 4 <artifactId>spring-retry</artifactId> 5 <version>1.3.1</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> 8 <dependency> 9 <groupId>org.aspectj</groupId> 10 <artifactId>aspectjweaver&l....
Centos7 Nacos安装 有更新! 2022-02-26 环境 CentOS7 64bit JDK8+; Maven 3.2.x+; 下载 zip 包 https://github.com/alibaba/nacos/releases 两种解压方式,看个人喜好。本文使用 unzip 下载的 zip 包。 上传至服务器,解压 1unzip nacos-server-2.0.3.zip 进入 nacos/bin 目录 1cd nacos/bin 执行 startup.sh 1sh startup.sh -m standalone 查看启动日志 1cd 2cd nacos/bin/logs 3cat start.out 启动成功 网址输入 服务器 IP:8848/nacos 例如:127.0.0.1:8848/nacos 默认用户名密码都是 nacos 登录成功
Navicat连接数据库报错 Host XXX is not allowed to connect to this MySQL server 2022-02-17 因为 MySQL 配置了不支持远程连接引起的 解决 1、在服务器中登录 MySQL root 用户 1mysql -u root -p 2、依次执行命令 1use mysql; 2 3select host from user where user='root'; 3、将 host 设置为通配符 Host 列指定了允许用户登录所使用的 IP,比如 user=root Host=192.168.1.1。这里的意思就是说 root 用户只能通过 192.168.1.1 的客户端去访问。 user=root Host=localhost,表示只能通过本机客户端去访问。而 % 是个通配符,如果 Host=192.168.1.%,那么就表示只要是 IP 地址前缀为“192.168.1.”的客户端都可以连接。如果 Host=%,表示所有 IP 都有连接权限。 1update user set host = '%' where user = 'root'; 4、修改完成后执行 flush privileges 使配置立即生效 1flush privileges; 5、再次使用 nav....
日常开发bug记录 2022-02-16 场景 查询数据库中时间区间内的数据 由于一些细节操作,我需要在后端将时间截取,只要年月日。 这里用到了 hutool 的 DateUtil 工具中的 parse 和 format 方法解析。 1 String endDate = "2022-02-14 59:59:59"; 2 String format = DateUtil.format(DateUtil.parse(endDate), "yyyy-MM-dd"); 3 System.out.println(format); 最后结果 原因 请求参数因为是 59:59:59,正确应为 23:59:59 这里是 59,所以工具会给加两天的时间,14 就变成了 16 一定要擦亮眼睛!