SQL调优:让Java内存分担计算

作者: 剽悍一小兔

CSDN前端优质创作者,打破编程小说次元壁第一人《JavaScript百炼成仙》作者,专注Java硬核干货分享,分享创造快乐,技术成就梦想!

我们在工作中,经常会因为一条慢sql调半天。这一节,我给大家介绍一种提升查询效率的思路,那就是让Java内存帮我们分担一些运算。

案例还是采用 springBoot日记本系统,源码下载地址和教程在文末。

先改一个BUG

之前遗留了一个BUG需要我们解决,就是在日记的详情页,日记类型没有做转换。

让我们看下controller:

@RequestMapping("diary/{id}.html")
@SaCheckLogin
public ModelAndView getDiary(@PathVariable Long id, ModelAndView mav){
    TblSynBlog tblSynBlog = blogService.selectOne(id);
    mav.addObject("blog",tblSynBlog);
    mav.addObject("statistics",blogService.getBlogsStatistics());
    mav.setViewName("detail");
    return mav;
}

破案了,代码中直接把tblSynBlog放到了modelAndView中,没有对Type进行专门的处理。

现在开始改BUG:

思路很简单,根据日记的type去类型表查询具体的中文是啥,再返回就可以了。

@RequestMapping("diary/{id}.html")
@SaCheckLogin
public ModelAndView getDiary(@PathVariable Long id, ModelAndView mav){
    TblSynBlog tblSynBlog = blogService.selectOne(id);
    //对Type进行中文转义
    SysBlogType type = sysBlogTypeService.getByTypeId(tblSynBlog.getBlogType());
    mav.addObject("blogType",type.getTypeName());

    mav.addObject("blog",tblSynBlog);
    mav.addObject("statistics",blogService.getBlogsStatistics());
    mav.setViewName("detail");
    return mav;
}

ISysBlogTypeService

SysBlogType getByTypeId(String blogType);

SysBlogTypeServiceImpl

@Override
public SysBlogType getByTypeId(String blogType) {
    return baseMapper.selectById(Integer.parseInt(blogType));
}

我们一般不推荐直接在controller引入mapper,这是规范,还是老老实实写service吧。

detail.jsp

<div class="title2">发布时间:${blog.createDate} &nbsp;&nbsp;&nbsp; 日志类别:${blogType}</div>

成果

搞定。

新需求

刚才的一套操作行云流水一般,现在我们来思考一个问题。假如我从数据库查询出一个List,需要给这个List额外增加一个字段,这个新字段需要从别的表里面查询,该怎么办?

比如,我现在要在类型管理页面增加对应类型的日记数量。

这是类型管理的页面。

我们打算加一列,显示文章的总数量。

一个简单的思路就是,先获取类型的列表,然后一次按照类型去查询对应文章的数量。

页面用的是axios异步查询的数据。

getData(){
  var index = layer.load(1); //添加laoding,0-2两种方式
  axios.post('${basePath}/sys-blog-type/selectAll',{}).then(r =>{
    layer.close(index);    //返回数据关闭loading
    if(r.data.code != '0000'){
      layer.msg(r.data.message,{icon:2});
      return;
    }
    console.log(r.data.data);
    this.listData = r.data.data;
  }).catch(error => {
    layer.msg(error.response.status,{icon:2});
    layer.close(index);    //返回数据关闭loading
  })
},

SysBlogTypeController

@RequestMapping("/selectAll")
public List<SysBlogType> selectAll(){
    return sysBlogTypeService.selectAll();
}

SysBlogTypeServiceImpl

@Override
public List<SysBlogType> selectAll() {
    QueryWrapper<SysBlogType> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_id", StpUtil.getLoginId());
    return sysBlogTypeMapper.selectList(queryWrapper);
}

代码一目了然,就是结合MybatisPlus做了条件查询。 我们通过controller发现,返回给前端的是List,我们需要增加一列,就需要在这里添加一个字段。

@TableField(exist = false)
private Integer blogNumber;

加上注解@TableField(exist = false)是因为这个字段只是返回给前端用的,不需要和数据库表做绑定。

修改service

@Autowired
BlogMapper blogMapper;

@Override
public List<SysBlogType> selectAll() {
    QueryWrapper<SysBlogType> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("user_id", StpUtil.getLoginId());
    List<SysBlogType> sysBlogTypes = sysBlogTypeMapper.selectList(queryWrapper);
    sysBlogTypes.forEach(e -> {
        Integer typeId = e.getId();
        Integer count = blogMapper.selectCount(new LambdaQueryWrapper<TblSynBlog>()
                .eq(TblSynBlog::getBlogType, typeId));
        e.setBlogNumber(count);
    });
    return sysBlogTypes;
}

这几行代码是遍历博客类型,计算每个类型下的博客数量,并将数量设置到博客类型实体类中的一个blogNumber属性中。

页面代码修改:

效果:

目的是达到了,但是假如类型非常多,就会导致for循环耗时过长。所以,我们一般不推荐在for循环里面再去查询数据库的。

优化:我们可以先把博客信息查询出来,然后用内存去计算。

@Override
public List<SysBlogType> selectAll() {
  // 创建查询条件对象
  QueryWrapper<SysBlogType> queryWrapper = new QueryWrapper<>();
  // 设置查询条件:用户ID等于当前登录用户的ID
  queryWrapper.eq("user_id", StpUtil.getLoginId());
  // 查询符合条件的博客分类列表
  List<SysBlogType> sysBlogTypes = sysBlogTypeMapper.selectList(queryWrapper);
  // 获取所有博客分类的ID
  Set<Integer> blogIds = sysBlogTypes.stream().map(SysBlogType::getId).collect(Collectors.toSet());
  // 根据博客分类ID查询对应的博客列表
  List<TblSynBlog> tblSynBlogs = blogMapper.selectList(new LambdaQueryWrapper<TblSynBlog>()
          .in(TblSynBlog::getBlogType, blogIds));
  // 将博客列表按照分类ID进行分组
  Map<String, List<TblSynBlog>> tblSynBlogsMap = tblSynBlogs.stream().collect(Collectors.groupingBy(TblSynBlog::getBlogType));
  // 遍历博客分类列表,设置每个博客分类对应的博客数量
  sysBlogTypes.forEach(e -> {
      List<TblSynBlog> synBlogs = tblSynBlogsMap.get(e.getId() + "");
      if (synBlogs != null) {
          e.setBlogNumber(synBlogs.size());
      } else {
          e.setBlogNumber(0);
      }
  });
  // 返回博客分类列表
  return sysBlogTypes;
}

数据不多的话,看不出啥,但是如果数据很多,性能会有一个显著的提升。

源码下载

这个案例我是在springboot日记本系统里面完成了,有需要源码的小伙伴直接clone这个项目即可。

文字教程:

https://blog.csdn.net/weixin_39570751/category_11699146.htmlhttps://blog.csdn.net/weixin_39570751/category_11699146.html

https://gitee.com/skyblue0678/diary

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins集成钉钉通知插件的具体步骤怎么做你知道吗?

最近公司要求工作务必使用钉钉&#xff0c;其他聊天软件不再用于工作沟通了。虽然很抓狂&#xff0c;但是上面的决定不可违逆&#xff0c;只好转战钉钉。虽然强制使用钉钉挺令人反感的&#xff0c;但阿里在这款软件上确实下了些功夫&#xff0c;比如jenkins集成钉钉通知插件后&…

MySQL 数据库基础

这里写目录标题 一、Mysql的基本概念数据库管理系统&#xff08;DBMS&#xff09;数据库系统 二、数据库的发展史三、 主流的数据库介绍数据库分为关系型数据库与非关系型数据库关系型数据库非关系型数据库介绍 四、 操作Mysql常用的数据类型&#xff1a;常看数据库结构查看当前…

Linux内核中内存管理相关配置项的详细解析16

接前一篇文章&#xff1a;Linux内核中内存管理相关配置项的详细解析15 三十五、Data Access Monitoring 此项展开后如下图所示&#xff1a; “DAMON: Data Access Monitoring Framework”项默认不选中。如果将其选中&#xff0c;则页面变为&#xff1a; 1. DAMON: Data Access…

Kafka学习---1、Kafka 概述、Kafka快速入门

1、Kafka概述 1.1 定义 1、Kafka传统定义&#xff1a;Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue)&#xff0c;主要是应用于大数据实时处理领域。 2、发布/订阅&#xff1a;消息的发布者不会将信息直接发送给特定的订阅者&#xff0c;而是将发布的信息分…

系统稳定性与高可用保障

一、前言 高并发、高可用、高性能被称为互联网三高架构&#xff0c;这三者都是工程师和架构师在系统架构设计中必须考虑的因素之一。今天我们就来聊一聊三 H 中的高可用&#xff0c;也是我们常说的系统稳定性。 > 本篇文章只聊思路&#xff0c;没有太多的深入细节。阅读全…

大数据分析案例-基于逻辑回归算法构建心脏病发作预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

几个直接在TigerISP上查看全志芯片接Sensor分辨率的方法

TigerISP是全志提供的量产工具&#xff0c;在连接TigerISP时需要填写Sensor名称、Sensor分辨率、Sensor帧率及选择ISP通道、Vich、Wdr模式等… 准备工作&#xff1a;打开debugfs 操作&#xff1a;adb shell进入系统后输入以下两个命令&#xff1a; mount -t debugfs mone /s…

【办公类-30-01】(Python)大班毕业证书批量打印(幼儿信息、性别、毕业日期、学校、公章、签名、证书日期)

背景需求 大班毕业在即&#xff0c;需要打印大班幼儿毕业证书。&#xff08;已有打印好的彩色证书&#xff09; 常规操作模式&#xff1a; 1&#xff0c;统一盖章&#xff0c;反复签字 200份证书&#xff0c;每张证书上需要盖园所章、园长签字200次 2. 每个班主任自己领取班…

服务日志性能调优,由log引出的巨坑

只有被线上服务问题毒打过的人才明白日志有多重要&#xff01; 谁赞成&#xff0c;谁反对&#xff1f;如果你深有同感&#xff0c;那恭喜你是个社会人了&#xff1a;&#xff09; 日志对程序的重要性不言而喻&#xff0c;轻巧、简单、无需费脑&#xff0c;程序代码中随处可见…

Spring事物失效的八大场景

1.方法内的自调用&#xff1a;spring事物是基于aop的&#xff0c;只要使用代理对象调用某个方法时&#xff0c;spring事物才能生效&#xff0c;而在一个方法内使用this.xxx()时。this并不是代理对象&#xff0c;所以会失效&#xff08;实际上是transaction注解失效&#xff09;…

64位和32位相比优势是什么(一)

前置知识&#xff1a;程序是如何执行的&#xff1f; 一道常规的面试题&#xff1a;相比 32 位&#xff0c;64 位的优势是什么&#xff1f; 面试官考察这种类型的问题&#xff0c;主要是想看求职者是否有扎实的计算机基础&#xff0c;同时想知道求职者在工作中是否充满好奇&am…

渲染案例 | 《妈妈的牵牛花》荣获厦门国际动漫节金奖

2023年5月25日&#xff0c;第十五届厦门国际动漫节“金海豚奖”动画组获奖名单公布。其中&#xff0c;蓝海创意云《青团计划》优秀代表作品——《妈妈的牵牛花》荣获最佳学生动画金奖。 蓝海创意云作为行业内知名的影视动画渲染服务商&#xff0c;深度参与《妈妈的牵牛花》的后…

【CSS】文字扫光 | 渐变光

码来 可调整角度与颜色值来改变效果 <p class"gf-gx-color">我是帅哥</p> <style>.gf-gx-color {background: -webkit-linear-gradient(135deg,red,red 25%,red 50%,#fff 55%,red 60%,red 80%,red 95%,red);-webkit-text-fill-color: transparen…

systemctl 命令设置开机自启动失败

1.案例现象 我在 3 月 31日的时候发表了一篇《shell 脚本之一键部署安装 Nginx 》&#xff0c;介绍了如何通过 shell 脚本一键安装 Nginx 我脚本中执行了 Nginx 开机自启动的命令&#xff0c;当我使用 systemctl status nginx 命令复核的时候&#xff0c;我发现 Nginx 服务设…

Vue.js中的两大指令:v-on和v-bind,实现页面动态渲染和事件响应

Vue.js中的两大指令&#xff1a;v-on和v-bind&#xff0c;实现页面动态渲染和事件响应 一、Vue指令&#xff08;一&#xff09;v-bind指令&#xff08;二&#xff09;v-on指令1. 基本使用&#xff08;1&#xff09;最基本的语法 2. Vue中获取事件对象(了解)3. v-on 事件修饰符4…

树莓派安装 VScode 与卸载 VScode

0. 实验准备 一个带有系统的树莓派&#xff08;有屏幕更好&#xff09; 一台联网的电脑&#xff0c;且可以使用 VNC 登录树莓派&#xff08;与屏幕二选一&#xff09; 一个可以与树莓派交互文件的软件、如&#xff1a;MobaXterm&#xff08;推荐&#xff09;、WinSCP 1. 获取…

AI制作口播视频,原来这么简单

&#x1f4a1;大家好&#xff0c;我是可夫小子&#xff0c;《小白玩转ChatGPT》专栏作者&#xff0c;关注AIGC、读书和自媒体。 在前面的文章中&#xff0c;我们介绍了生成自己专属卡通形象照&#xff0c;这张照片不仅能作头像&#xff0c;还可以让照片说话&#xff0c;作为我们…

【面试题】前端面试 15 问高频题

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 数组去重 遍历旧数组&#xff0c;然后拿着旧数组元素去查询新数组&#xff0c;如果该元素…

Redis的主从复制、哨兵机制、集群

一、主从复制 1、定义 主&#xff1a;master以写为主当master数据变化的时候从&#xff1a;slave以读为主自动将新的数据异步同步到其他slave数据库 2、作用 读写分离、容灾恢复、数据备份、水平扩容支撑高并发。 3、使用方式——配从不配主 权限配置&#xff1a;master如…

Mysql数据库基础和增删改查操作(每一次「欢喜」都值得纪念)

文章目录 一、数据库基本概念数据表数据库数据库管理系统(DBMS)数据库系统 二、数据库类型和常用数据库1.关系型数据库2.非关系型数据库 三、数据库的数据类型四、SQL语句1.简介2.分类 五、SQL语句的使用1.数据库操作&#xff08;1&#xff09;创建数据库 2.数据库表操作&#…