我们后端程序员不是操作MyBatis的CRUD Boy

news2024/11/23 6:17:41

大家好,我是南哥。

一个对Java程序员进阶成长颇有研究的人,今天我们接着新的一篇Java进阶指南。

为啥都戏称后端是CRUD Boy?难道就因为天天怼着数据库CRUD吗?要我说,是这个岗位的位置要的就是你CRUD,你不得不CRUD。哪有公司天天能给你搭建高并发、高可用、大数据框架的活呢,一条业务线总要成长吧,慢慢成熟了就要装修工来缝缝补补、美化美化,也就是CRUD的活。

不能妄自菲薄CRUD Boy,我们是后端工程师。今天来指南下操作数据库之MyBatis框架。

本文收录在我开源的《Java学习面试指南》中,一份覆盖Java程序员所需掌握核心知识、面试重点的Java指南,目前已经更新到近200道面试官必考的面试题。希望收到大家的 ⭐ Star ⭐支持。GitHub地址:https://github.com/hdgaadd/JavaGetOffer,相信你看了一定不会后悔。

在这里插入图片描述

文章目录

    • 1. Mybatis概要
      • 1.1 Mybatis理解
      • 1.2 SqlSession是什么
    • 2. Mybatis缓存
      • 2.1 Mybatis缓存分类
      • 2.2 Mybatis缓存局限性
    • 3. Mybatis分页插件

1. Mybatis概要

1.1 Mybatis理解

面试官:你说下对MyBatis的理解?

如果没有MyBatis的支持,大家是怎么实现通过程序控制数据库的?首先我们需要为程序引入MySQL连接依赖mysql-connector.jar,加载数据库JDBC驱动,接着创建数据库连接对象Connection、SQL语句执行器Statement,再把SQL语句发送到MySQL执行,最后关闭SQL语句执行器和数据库连接对象。

整个过程是比较繁琐的,这是通过JDBC操作MySQL必走的过程。可实际开发可给不了你那么多时间,如果大家非要用JDBC去写大量的冗余代码也可以,能抗住催你开发进度的压力就行。

这是JDBC操作的过程。

public class JDBCController {
    private static final String db_url = "jdbc:mysql://localhost:3306/db_user";
    private static final String user = "root";
    private static final String password = "root";
    
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        String sql = "select * from user order by id desc";
        try {
            connection = DriverManager.getConnection(db_url, user, password);
            statement = connection.createStatement();
            int result = statement.executeUpdate(sql);
            System.out.println(result);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

MyBatis能帮助我们什么?早在2002年,MyBatis的前身iBatis诞生,并于2010年改名为MyBatis。该框架引入了SQL映射作为持久层开发的一种方法,也就是说我们不需要把SQL耦合在代码里,只需要把SQL语句单独写在XML配置文件中。

以下是MyBatis编写SQL的写法。SQL的编写已经和程序运行分离开,消除了大量JDBC冗余代码,同时MyBatis还能和Spring框架集成。整个SQL编写的流程变得更加灵活也更加规范化

@Mapper
public interface UserMapper extends BatchMapper<UserDO> {
    List<UserDO> selectAllUser();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.JavaGetOffer.UserDO">

    <select id="selectAllUser" resultType="org.JavaGetOffer.UserDO">
        select * from user order by id desc
    </select>
    
</mapper>

1.2 SqlSession是什么

面试官:那SqlSession知道吧?

从我们偷偷访问某个小网站开始,到我们不耐烦地关闭浏览器或者退出登录时,我们作为用户和网站的一次会话就结束了。MyBaits框架要访问数据库同样要与数据库建立通信桥梁,而SqlSession对象表示的就是MyBaits框架与数据库建立的会话

我们可以利用SqlSession来操作数据库,如下代码。

    @Test
    public void testMybatis() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<UserDO> userList = userMapper.listAllUser();
        System.out.println(JSON.toJSONString(userList));
    }

2. Mybatis缓存

2.1 Mybatis缓存分类

面试官:Mybatis的缓存有哪几种?

软件系统合理使用缓存有一个好处。有了缓存,在原始数据没有更新的情况下,我们不需要重新再去获取一遍数据,这也减少了数据库IO,达到提升数据库性能的目的。

MyBatis同样提供了两个级别的缓存,一级缓存是基于上文提到的SqlSession实现,二级缓存是基于Mapper实现。

一级缓存作用在同一个SqlSession对象中,当SqlSession对象失效则一级缓存也跟着失效。我们梳理下一级缓存的生命周期。首先第一次查询时会把查询结果写入SqlSession缓存,如果第二次查询时原始数据没有改变则会读取缓存,但如果是修改、删除、添加语句的执行,那SqlSession缓存会被全部清空掉,这也是为了防止脏读的出现。

一级缓存缓存底层使用的是一个简单的Map数据结构来存储缓存,其中key为SQL + 参数、val为查询结果集。一级缓存的生命周期如下。

在这里插入图片描述

二级缓存的作用域是同一个命名空间namespace的Mapper对象,也就是说同一个Mapper下的多个SqlSession是可以共用二级缓存的。二级缓存的缓存写入、清空流程和一级缓存相似,但二级缓存的生命周期是和应用程序的生命周期一致的。为什么?因为Mybatis框架与Spring IOC集成的Mapper对象是单例对象。

另外大家还需要注意下,Mybatis的一级缓存是默认开启的且不能关闭,而二级缓存则需要我们手动开启,我们需要在配置文件中配置cacheEnabled参数。

<configuration>
  <settings>
    <setting name="cacheEnabled" value="true"/>
  </settings>

2.2 Mybatis缓存局限性

面试官:那Mybatis缓存有什么问题吗?

缓存是好,就是问题有点多,目前大厂大都禁止了Mybatis缓存的使用。

南哥总结了下,主要有以下原因。

(1)适用场景少

Mybatis二级缓存更适用于读多写少的业务场景,但是对于细粒度的缓存支持并不友好。举个用烂了的商城例子,每个商品信息的更新是非常频繁的的,而让用户每次都看到的是最新的商品信息又非常重要。

在同一个namespace的Mapper中一般会包含多个商品信息的二级缓存,只要有某一个商品信息更新了,则所有商品缓存都会全部失效。那其实在这个业务场景中,二级缓存的存在已经没有多大必要了,还反而增加了系统复杂性。

(2)数据不一致性问题

如果多个不同namespace的Mapper都共同操作同一个数据库表的情况下,第一个Mapper更新了数据库表会清空它本身的二级缓存,但其他namespace的Mapper是没有感知的,仍然缓存的是旧数据,数据不一致的问题就出现了。

(3)不适用于分布式系统

现在还用单机部署的业务已经不多了,大家都紧跟潮流搭了个分布式、高可用的系统。在分布式系统中,如果每个节点都使用自己的本地缓存,假如现在节点A更新了缓存,但节点B、节点C是不会进行同步更新的,同样产生了数据不一致的问题。

3. Mybatis分页插件

面试官:Mybatis分页插件是怎么实现的?

Mybatis分页的原理其实很简单,没有想象的那么复杂。我们只需要拦截SQL查询语句,再把SQL语句作为子查询,外面包裹一层SELECT * FROM后再加上LIMIT的分页约束语句。

如下SQL示例,确实挺简单的。

SELECT * FROM user
SELECT u.* FROM (SELECT * FROM user) u LIMIT M, N

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

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

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

相关文章

FastAPI教程II

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial Cookie参数 定义Cookie参数与定义Query和Path参数一样。 具体步骤如下&#xff1a; 导入Cookie&#xff1a;from fastapi import Cookie声明Cookie参数&#xff0c;声明Cookie参数的方式与声明Query和Path参数…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue

CMSIS 2.0接口中的消息&#xff08;Message&#xff09;功能主要涉及到实时操作系统&#xff08;RTOS&#xff09;中的线程间通信。在CMSIS 2.0标准中&#xff0c;消息通常是通过消息队列&#xff08;MessageQueue&#xff09;来进行处理的&#xff0c;以实现不同线程之间的信息…

650V 1200V 碳化硅MOS TO247 封装 内阻30毫欧 40 80毫欧

650V 1200V 碳化硅MOS TO247 封装 内阻30毫欧 40 80毫欧

Java的IO体系

目录 1、Java的IO体系2、IO的常用方法3、Java中为什么要分为字节流和字符流4、File和RandomAccessFile5、Java对象的序列化和反序列化6、缓冲流7、Java 的IO流中涉及哪些设计模式 1、Java的IO体系 IO 即为 input 输入 和 output输出 Java的IO体系主要分为字节流和字符流两大类…

MySQL中的redo log 和 undo log

undo log和redo log 先引入两个概念&#xff1a; 当我们做了一些操作 (update/delete/insert)&#xff0c;提交事务后要操作MySql中的数据。 为了能够提升性能&#xff0c;引入了两块区域&#xff1a;内存结构和磁盘结构。 磁盘结构&#xff1a; 主要存储的就是数据页&#x…

LeetCode 算法:二叉搜索树中第K小的元素 c++

原题链接&#x1f517;&#xff1a;二叉搜索树中第K小的元素 难度&#xff1a;中等⭐️⭐️ 题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从1开始计数&#xff09;。 示例 1&#xff1a;…

页面开发感想

页面开发 1、 前端预览 2、一些思路 2.1、首页自定义element-plus的走马灯 :deep(.el-carousel__arrow){border-radius: 0%;height: 10vh; }需要使用:deep(标签)才能修改样式 或者 ::v-deep 标签 2.2、整体设计思路 <template><div class"card" style&…

机器学习第四十五周周报 SAM优化器

文章目录 week45 SAM优化器摘要Abstract1. 题目2. Abstract3. 锐度感知最小化3.1 问题提出3.2 方法提出 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程 5. 结论6.代码复现小结参考文献 week45 SAM优化器 摘要 本周阅读了题为Sharpness-Aware Minimization for Efficien…

! Warning: `flutter` on your path resolves to

目录 项目场景&#xff1a; 问题描述 原因分析&#xff1a; 解决方案&#xff1a; 1. 检查并更新.bash_profile或.zshrc文件 2.添加Flutter路径到环境变量 3. 加载配置文件 4.验证Flutter路径 5.重新启动终端 项目场景&#xff1a; 今天重新安装了AndroidStudio,并配置…

Postman设置请求间自动保存返回参数,方便后续请求调用,减少复制粘贴

postman中常常出现&#xff1a;有两个请求&#xff0c;一个请求首先获取验证码或者token&#xff0c;再由得到的验证码或token编写body发送另一个请求。如何设置两个请求间自动关联相关数据呢&#xff1f; 通过环境存储全局变量 现在有两个请求如下图&#xff0c;生成验证码是…

如何制作鼠标悬浮后伸缩的搜索框

引言 许多博客都在使用的伸缩搜索框制作教程 成品展示&#xff08;颜色自行搭配&#xff09; 初步布局 居中盒子&&初始化样式 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewpo…

进程间通信简介-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

进程间通信简介 进程间通信简介 进程间进程简称IPC(interprocess communication)&#xff0c;进程间通信就是在不同进程之间传递信息或交换信息 进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的…

【Docker】集群容器监控和统计 CAdvisor+lnfluxDB+Granfana的基本用法

集群容器监控和统计组合&#xff1a;CAdvisorlnfluxDBGranfana介绍 CAdvisor&#xff1a;数据收集lnfluxDB&#xff1a;数据存储Granfana&#xff1a;数据展示 ‘三剑客’ 安装 通过使用compose容器编排&#xff0c;进行安装。特定目录下新建文件docker-compose.yml文件&am…

使用Vercel 搭建自己的Dashy导航页

背景 Dashy 是一个开源的自托管导航页面配置服务&#xff0c;它具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。用户可以利用 Dashy 将自己常用的一些网站聚合起来&#xff0c;形成一个个性化的导航页面。 同类的竞品还有Heimdall, Flare 等。 可以通过Docker 等…

uniapp,uni-fab组件拖动属性,替代方案

文章目录 1. 背景2. 替代方案2.1 方案一2.2 方案二参考1. 背景 最近基于uniapp开发一款设备参数调试的APP软件,其中有使用到悬浮按钮,快速开发阶段,为了能尽快上线,直接使用了uni-ui的扩展组件uni-fab,参考【1】,效果如下图: 后期,相应的界面内容增多,由于uni-fab是…

TS_类型

目录 1.类型注解 2.类型检查 3.类型推断 4.类型断言 ①尖括号&#xff08;<>&#xff09;语法 ②as语法 5.数据类型 ①boolean ②number ③string ④undefined 和 null ⑤数组和元组 ⑥枚举 ⑦any 和void ⑧symbol ⑨Function ⑩Object 和 object 6.高…

在晋升受阻或遭受不公待遇申诉时,这样写是不是好一些?

在晋升受阻或遭受不公待遇申诉时&#xff0c;这样写是不是好一些&#xff1f; 在职场中&#xff0c;晋升受阻或遭受不公待遇是员工可能面临的问题之一。面对这样的情况&#xff0c;如何撰写一份有效的申诉材料&#xff0c;以维护自己的合法权益&#xff0c;就显得尤为重要。#李…

mathcup大数据竞赛论文中集成学习(或模型融合)的运用分析

ps: (模型融合和集成学习是两个紧密相关但又有所区别的概念。集成学习是一种更广泛的范式&#xff0c;而模型融合可以被视为集成学习的一种特殊形式或策略。) 1.集成学习原理 图1 如图1所示&#xff0c;集成学习是一种通过结合多个机器学习模型的预测来提高整体性能的策略。其…

【MongoDB】分布式数据库入门级学习

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;为祖国的科技进步添砖Java 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f8;友情提供 凯楠&#x1f4f8; - 不夜长安 目录 MongoDB 相关 数据库排行榜单 MongoDB 中文官网 菜鸟…

Linux开发讲课19--- SPI原理

一、概述 SPI&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种高速串行全双工的接口。最早由Motorola首先提出的全双工同步串行外围接口&#xff0c;采用主从模式(Master—Slave)架构&#xff0c;支持一个或多个Slave设备。SPI接口主要应用在EEPROM、F…