2024-04学习笔记

news2024/11/22 9:37:42

1.sql优化-子查询改为外连接

1.改之前

改之前是这样,那针对查出来的每一条数据,都要执行一次箭头所指的函数

执行的sql很慢

2.改之后

改之后是这样,整体做外连接,不用每一条都再执行一次查询

执行时间缩短了好几倍

 2.Mybatis中不要有太多空行

正常人的操作肯定是sql在工具里执行没问题了,再粘贴到Mybatis中

但是有个奇怪的现象,mybatis一执行就报错,就算我把控制台打印的sql沾到工具里边执行也没问题

 Caused by: java.util.concurrent.ExecutionException: net.sf.jsqlparser.parser.ParseException: 
Encountered unexpected token: "AND" "and"
    at line 8, column 1.

Was expecting:

    <EOF>

 然后把Mybatis中的空行删除之后,就好了

正常情况下  <if>标签是会去掉第一个and

个人觉得是因为接下来的<if>因为前边有空行,没办法识别and是否需要去掉

3.FIND_IN_SET函数

FIND_IN_SET( #{item}, a.sourceDatabaseName) > 0

FIND_IN_SET('子串','母串'),母串是逗号分割的,如果>0,说明子串是逗号分割后其中的一个元素

比如

子串是母串其中一个元素时候才返回true  如果子串是1,母串是11,就返回false了 

 母串和子串相等时候也返回true

 4.GROUP_CONCAT(字段  SEPARATOR 分隔符 )函数

这个1中介绍过了,可以和group by一起用,也可以作为子查询时候使用

适用于把多个结果用符号分割拼一起

4.1子查询时候使用

select devInstance.inst_id as                        id,
       (SELECT GROUP_CONCAT(dbInput.source_database_name SEPARATOR ';') name
        from sys_data_develop_db_input dbInput
        where dbInput.task_id = devInstance.task_id) source
from sys_data_develop_instance devInstance

出来得结果就是

1  a;b;c

2  a;c;d

4.2.和group by一起使用

SELECT dbInput.task_id,
       GROUP_CONCAT(dbInput.source_database_name SEPARATOR ',') databaseName,
       GROUP_CONCAT(dbInput.source_table_name SEPARATOR ',')    tableName
from sys_data_develop_db_input dbInput
group by dbInput.task_id

5.pom.xml中得option

6. Mybatis传入了Map<Integer,List<String>>

    /**
     * key是类型,value是该类型对应的id,不同表中id类型不同所以统一用string接收
     * 
     */
    Map<Integer,List<String>> taskIdMap;

mybatis,循环key时候用 OR 隔开

<if test="queryParams.taskIdMap != null and queryParams.taskIdMap.size()>0">
                         and
                         <foreach item="list" index="key" collection="queryParams.taskIdMap" open="(" separator=" OR " close=")">
                             (a.taskType = #{key}
                             and a.id in
                             <foreach item="item" collection="list" open="(" separator="," close=")">
                                 #{item}
                             </foreach>
                             )
                         </foreach>
                     </if>

执行时控制台打印

 AND (
         (a.taskType = ? AND a.taskId IN (?, ?)) 
        OR
         (a.taskType = ? AND a.taskId IN (?))
    )

7.Mybatis缓存

7.1一级缓存

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。

Mybatis默认开启一级缓存。 

 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

 7.2二级缓存

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,

不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,

第一次执行完毕会将数据库中查询的数据写到缓存(内存),

第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。

Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

二级缓存:根据命名namespace、查询语句方法名及查询参数等拼接的一个缓存key,value值是第一次从数据库查询出来的结果

但是避免使用二级缓存 

会有脏数据存在。因为同一个namespace下发生删改查才会清缓存,但是别人的namespace下对这个表有修改 是不会删缓存的  所以往下执行的之后还是旧数据 

 8.同步异步 阻塞非阻塞

阻塞 非阻塞 指的是线程的状态

9.同样的sql在不同环境下,执行时间差异很大

数据量的问题

dev比test多了190万数据,把没用的数据删除了就好了

10.垃圾回收与资源利用

 空间不够会GC,GC要stop the world,所以尽量减少GC

垃圾回收--堆
逃逸分析--栈
所以在栈中不断new 对象  可以避免垃圾回收

 

 

 池化:数据库连接池,线程池

11.MapStruct把两个实体映射到同一个实体上

后端来源的表不同,对应的实体也不同。但是返回给前端的时候是几个表一起返回

这时候就涉及到多个实体去映射到一个实体上

12.Springboot内置的tomcat

在start下有tomcat

13.集群和微服务

集群和分布式概念不同

集群,每个服务器做的事情相同

分布式,每个子节点做的事情不同

分布式和集群可以整合

比如现在每个微服务都是多实例,每个微服务在整体业务系统中只负责自己一块的业务,这些个集群整合在一起才是一个完整的业务系统

14.发令枪

await() 方法是用来阻塞线程的,等待倒计锁被减到0的时候,才会唤醒该方法继续执行。也可以设置等待超时时间

 15.Redis

1.IO多路复用

 2.备份

 

3.生活中使用的Redis

 1.redis计数

阅读量,访问量

 

2.购物车列表

那些图片可以写个接口异步加载,其他信息可以直接从redis取

 

 3.公众号,最新发布的消息放在最前边

用redis命令实现,类似栈,先进先出

4.朋友圈点赞

 

4.慢查询

 

5.主从

 

 

哨兵模式  先搭主从 再搭哨兵

 6.redis集群

 

扩容之后需要重新分配槽点,以及转移 数据

16.SSE

sse(​​Server Sent Event​​),直译为服务器发送事件,顾名思义,也就是客户端可以获取到服务器发送的事件

如果前端给后端发送一次消息后就不再发送消息,可以用SSE

比如我们项目的应用场景,前端把数据提交给后端之后,前端在页面上等待后端的返回信息

后端会持续不断的返回,每一种情况的校验结果

下面是我写的DEMO,分三种情况

全都测试过的,建议第二种第三种更好

@Api(tags = "sse测试")
@RestController
@RequestMapping("/api/v1/sse")
@RequiredArgsConstructor
@Slf4j
public class SSEController {

    private final SysDataCollectionOfflineTaskService service;

    /**
     * 测试通过的
     * @param response
     * @param collectionOfflineTaskForm
     */
    @PostMapping(value = "/get")
    public void push(HttpServletResponse response, @RequestBody CollectionOfflineTaskForm collectionOfflineTaskForm) {
        //接收前端传来得参数
        String id = collectionOfflineTaskForm.getId();
        log.info(id);
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("utf-8");
        PrintWriter pw = null;
        try {
            for (int i = 0; i < 3; i++) {
                Thread.sleep(1000);
                pw = response.getWriter();
                //todo 这里result是模拟业务逻辑处理得返回值
                Result<String> result = Result.success("测试");
                String json = JSONObject.toJSONString(result);
                //注意返回数据必须以data:开头,"\n\n"结尾
                //postman能看到返回的只有json数据 并没有前边得"data:"和后边的"\n\n"
                pw.write("data:" + json + "\n\n");
                pw.flush();
                //检测异常时断开连接
                if (pw.checkError()) {
                    log.error("客户端断开连接");
                    pw.close();
                    return;
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            if (Objects.nonNull(pw)) {
                pw.close();
            }
        }
    }

    /**
     * 测试通过的
     * 返回类型必须SseEmitter
     * @param collectionOfflineTaskForm
     * @return
     */
    @PostMapping("/events")
    public SseEmitter handleEvents(@RequestBody CollectionOfflineTaskForm collectionOfflineTaskForm) {
        //接收前端传来得参数
        String id = collectionOfflineTaskForm.getId();
        log.info(id);
        SseEmitter emitter = new SseEmitter();
        Result<String> result = Result.success("测试");
        //需要开启新线程 在一个新的线程中发送事件数据。这样可以确保主线程不会被阻塞,同时能够实现实时的事件流向客户端。
        new Thread(() -> {
            try {
                for (int i = 0; i < 3; i++) {
                    emitter.send(SseEmitter.event().data(result));
                    Thread.sleep(1000);
                }
                emitter.complete();
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }

    /**
     * 测试通过
     * @Async异步
     * @param collectionOfflineTaskForm
     * @return
     */
    @PostMapping("/test")
    public SseEmitter test(@RequestBody CollectionOfflineTaskForm collectionOfflineTaskForm) {
        //接收前端传来得参数
        String id = collectionOfflineTaskForm.getId();
        log.info(id);
        //需要开启新线程 在一个新的线程中发送事件数据。这样可以确保主线程不会被阻塞,同时能够实现实时的事件流向客户端。
        SseEmitter emitter = new SseEmitter();
        service.sseTest(emitter);
        return emitter;
    }
}
    @Override
    @Async
    public void sseTest(SseEmitter emitter) {
        Result<String> result = Result.success("测试");
        //需要开启新线程 在一个新的线程中发送事件数据。这样可以确保主线程不会被阻塞,同时能够实现实时的事件流向客户端。
        //new Thread(() -> {
        try {
            for (int i = 0; i < 3; i++) {
                emitter.send(SseEmitter.event().data(result));
                Thread.sleep(1000);
            }
            emitter.complete();
        } catch (IOException | InterruptedException e) {
            emitter.completeWithError(e);
        }
        //}).start();
    }

postman测试结果如图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1634577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

21.Nacos集群搭建

模拟Nacos三个节点&#xff0c;同一个ip,启动三个不同的端口&#xff1a; 节点 nacos1, 端口&#xff1a;8845 节点 nacos2, 端口&#xff1a;8846 节点 nacos3, 端口&#xff1a;8847 1.搭建数据库&#xff0c;初始化数据库表结构 这里我们以单点的数据库为例 首先新建一…

Facebook全攻略:从注册到养号再到防封,一篇搞定!

作为海外热门的社交媒体平台之一&#xff0c;Facebook已经成为品牌营销的重要渠道。很多新手小白在拿到Facebook账号后还是不知道如何操作&#xff0c;今天为大家准备了一份Facebook操作全攻略&#xff0c;从注册、养号到防封号&#xff0c;让你的Facebook跨境之旅更加顺畅&…

小程序地理位置接口怎么开通?

小程序地理位置接口有什么功能&#xff1f; 如果我们提审后驳回理由写了“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通&#xff0c;建议完成接口开通后或移除接口相关内容后再进行后续版本提审”&#xff0c;如果你也碰到类似问题&#xf…

Ansys Speos|进行智能手机镜头杂散光分析

本例的目的是研究智能手机Camera系统的杂散光。杂散光是指光向相机传感器不需要的散光光或镜面光&#xff0c;是在光学设计中无意产生的&#xff0c;会降低相机系统的光学性能。 在本例中&#xff0c;光学透镜系统使用Ansys Zemax OpticStudio (ZOS)进行设计&#xff0c;并使用…

使用 GitHub Actions 实现项目的持续集成(CI)

目录 什么是 GitHub Actions 基础概念 Workflow 文件 Workflow 语法 实例&#xff1a;编译 OpenWrt 什么是 GitHub Actions GitHub Actions 是 GitHub 推出的持续集成&#xff08;Continuous Integration&#xff0c;简称 CI&#xff09;服务它允许你创建自定义工作流&am…

源码编译framework.jar 并成功导入android studio 开发

一、不同安卓版本对应路径 Android N/O: 7 和 8 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar Android P/Q: 9 和 10 out/soong/.intermediates/frameworks/base/framework/android_common/combined/framework.jar Android R: 11以上 out/so…

Qt下使用7Z源码进行压缩和解压缩

7Z压缩是一款常用的压缩算法和工具&#xff0c;本文主要介绍一款在qt环境下进行编译的压缩方法。 本人测试是可以正常跑通的&#xff0c;具体代码部分请下载&#xff1a;下载链接&#xff0c;提取码&#xff1a;ev9t 7z源码网址&#xff1a;7-Zip 7z简介&#xff1a; 7z 是…

有趣的大模型之我见 | Llama AI Model

Llama 开源吗&#xff1f; 我在写《有趣的大模型之我见 | Mistral 7B 和 Mixtral 8x7B》时曾犹豫&#xff0c;在开源这个事儿上&#xff0c;到底哪个大模型算鼻祖&#xff1f;2023 年 7 月 18 日&#xff0c;Meta 推出了最受欢迎的大型语言模型&#xff08;LLM&#xff09;的第…

opencv_23_高斯模糊

void ColorInvert::gaussian_blur(Mat& image) { Mat dst; GaussianBlur(image, dst, Size(0, 0), 15); // Size(2, 2), imshow("图像模糊2", dst); }

MySQL中SELECT语句的执行过程

2.1.1. 一条SELECT语句的执行过程 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层 Server层负责建立连接、分析和执行SQL存储引擎层负责数据的存储和提取&#xff0c;支持 InnoDB、MyISAM、Memory 等多个存储引擎&#xff0c;MySQL5.5以后默认使用InnoDB&#xff0…

什么是DDoS攻击?怎么防御DDoS攻击?

在网络安全领域&#xff0c;DDoS攻击一直是热门话题&#xff0c;随着网络技术的不断发展和网络环境的复杂化演变&#xff0c;DDoS攻击变得愈加频繁、更具破坏性。根据2023年网络安全态势研判分析年度综合报告&#xff0c;全年全网网络层的DDoS攻击次数达2.51亿次&#xff01;本…

五一前的最后一个工作日

最近在学习 Elasticsearch 的使用&#xff0c;也更了几篇文章了&#xff0c;后续的话应该要等到节后再说了&#xff08;因为真的背不动电脑回家&#xff09; 再来看下这次五一假期的组成&#xff0c;1 号到 5 号&#xff0c;共五天&#xff0c;其中 2 号是 28 号周日调休来的&a…

【leetcode面试经典150题】74. 填充每个节点的下一个右侧节点指针 II(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

【人工智能】AI赋能城市交通 未来城市的驱动力

前言 随着城市化进程的不断加速&#xff0c;交通拥堵、环境污染等问题日益凸显&#xff0c;人们对交通系统的效率和可持续性提出了更高的要求。在这样的背景下&#xff0c;智能交通技术正成为改善城市交通的重要驱动力。本文将探讨智能交通技术在解决城市交通挑战方面的应用和未…

信息化工作人员必备常识12——远程桌面的使用与技巧

信息化工作人员必备常识12——远程桌面的使用与技巧 前言信息化人员必备常识回顾&#xff08;不想看回顾的直接往下滑哦~&#xff09;pingtelnetnslookup命令ipconfig命令域名DNS本机DNS缓存查看与清理DNS劫持DNS污染&#xff08;域名服务器缓存投毒&#xff09; 远程桌面开启远…

Python多线程并不是真的并行执行

Python多线程虽然能够利用多个CPU核执行计算&#xff0c;但并不能真正执行多线程并行计算。因为在Python中&#xff0c;有一个全局解释锁&#xff08;GlobalInterpreter Lock&#xff0c;GIL&#xff09;&#xff0c;该锁的存在使得在同一个时间只有一个线程执行任务&#xff0…

TiDB 利用binlog 恢复-反解析binlog

我们知道TiDB的binlog记录了所有已经执行成功的dml语句&#xff0c;类似mysql binlog row模式 &#xff0c;TiDB官方也提供了reparo可以进行解析binlog&#xff0c;如下所示: [2024/04/26 20:58:02.136 08:00] [INFO] [config.go:153] ["Parsed start TSO"] [ts449…

软考中级之数据库系统工程师笔记总结(五)网络基础

作者&#xff1a;Maynor 博客之星大数据领域Top1,GitHub项目awesome-chatgpt-project作者, 腾讯云TDSQL-C数据库开发者, 全网技术矩阵粉丝7w 公众号&#xff1a;Maynor996随着信息技术的飞速发展&#xff0c;数据库已成为现代企业和组织不可或缺的数据管理工具。对于许多专业人…

pycharm安装pandas包

import pandas时提示未安装pandas&#xff0c;点击下图红框选项&#xff0c;进行pandas安装 pycharm底部会有安装中的提示 pycharm底部提示红框的内容&#xff0c;说明安装成功 这个时候就可以看到import pandas不再报错了

Spring-Mybatis-Xml管理(动态sql语句,sql语句复用)

目录 前置条件 动态SQL语句 动态删除数据 1.集合类型:数组 2.集合类型: List 型 SQL语句重用 说明 &#x1f9e8;前置条件 已经创建了实体类(这边举个例子) 实体类User表 表中的字段名User实体类的属性值id (bigint auto increment) 长整型 自动增长private Long iduser…