[SSM]在WEB中应用MyBtis

news2024/9/23 17:22:45

目录

MyBatis基础

5.1需求描述

5.2数据库表的设计和准备数据

5.3实现步骤

第一步:引入相关依赖

第二步:引入相关配置文件,放到resources目录下(全部放到类的根路径下)

第三步:前端页面index.html

第四步:创建pojo包、service包、dao包、web包、utils包,引入utils类

第五步:定义pojo类:Account

第六步:编写AccountDao接口,以及AccountDaoImpl实现类

第七步:AccountDaoImpl中编写了mybatis代码,需要编写SQL映射文件

第八步:编写AccountService接口以及AccountServiceImpl

第九步:编写AccountServlet

第十步:测试

5.4MyBatis核心对象的作用域


5.1需求描述

5.2数据库表的设计和准备数据

5.3实现步骤

第一步:引入相关依赖

<?xml version="1.0" encoding="UTF-8"?>
​
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
​
  <groupId>com.hhb</groupId>
  <artifactId>mybatis004-web</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
​
  <name>mybatis004-web Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
​
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
​
  <dependencies>
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.11</version>
    </dependency>
    <!--mysql驱动依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.29</version>
    </dependency>
    <!--logback依赖-->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!--servlet依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>
  </dependencies>
​
  <build>
    <finalName>mybatis004-web</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
 

第二步:引入相关配置文件,放到resources目录下(全部放到类的根路径下)

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="jdbc.properties"/>
    <environments default="mybatis">
        <environment id="mybatis">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="AccountMapper.xml"/>
    </mappers>
</configuration>

AccountMapper.xml

<?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="account">
</mapper>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
​
<configuration debug="false">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>[%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
​
    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
​
    <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
​
</configuration>

第三步:前端页面index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>银⾏账户转账</title>
</head>
<body>
<!--/bank是应⽤的根,部署web应⽤到tomcat的时候⼀定要注意这个名字-->
<form action="/bank/transfer" method="post">
 转出账户:<input type="text" name="fromActno"/><br>
 转⼊账户:<input type="text" name="toActno"/><br>
 转账⾦额:<input type="text" name="money"/><br>
 <input type="submit" value="转账"/>
</form>
</body>
</html>

第四步:创建pojo包、service包、dao包、web包、utils包,引入utils类

SqlSessionUtil

package com.hhb.web;
​
import com.hhb.exceptions.MoneyNotEnoughException;
import com.hhb.exceptions.TransferException;
import com.hhb.service.AccountService;
import com.hhb.service.impl.AccountServiceImpl;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerException;
import java.io.IOException;
​
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet {
    private AccountService accountService = new AccountServiceImpl();
​
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        String moneyStr = request.getParameter("money");
        double money = Double.parseDouble(moneyStr);
​
        try {
            //调用service的转账方法完成转账
            this.accountService.transfer(fromActno, toActno, money);
            //调用view完成展示结果
            response.sendRedirect(request.getContextPath() + "/success.html");
        } catch (MoneyNotEnoughException e) {
            response.sendRedirect(request.getContextPath() + "/error1.html");
        } catch (TransferException e) {
            response.sendRedirect(request.getContextPath() + "/error2.html");
        } catch (Exception e){
            response.sendRedirect(request.getContextPath() + "/error2.html");
        }
    }
}

第五步:定义pojo类:Account

package com.hhb.pojo;
​
/**
 * 账户类:封装账户数据
 */
public class Account {
    private Long id;
    private String actno;
    private Double balance;
​
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }
​
    public Long getId() {
        return id;
    }
​
    public void setId(Long id) {
        this.id = id;
    }
​
    public String getActno() {
        return actno;
    }
​
    public void setActno(String actno) {
        this.actno = actno;
    }
​
    public Double getBalance() {
        return balance;
    }
​
    public void setBalance(Double balance) {
        this.balance = balance;
    }
​
    public Account(Long id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }
​
    public Account() {
    }
}
​

第六步:编写AccountDao接口,以及AccountDaoImpl实现类

AccountDao

package com.hhb.dao;
​
import com.hhb.pojo.Account;
​
/**
 * 账户的DAO对象,负责t_act表中数据的CRUD
 */
public interface AccountDao {
    /**
     * 根据账号查询账户信息
     *
     * @param actno 账号
     * @return 账户信息
     */
    public Account selectByActno(String actno);
​
    /**
     * 更新账户信息
     *
     * @param account 被更新的账户对象
     * @return 1表示更新成功,其它值表示更新失败
     */
    public int updateByActno(Account account);
}
 

AccountDaoImpl

package com.hhb.dao.impl;
​
import com.hhb.dao.AccountDao;
import com.hhb.pojo.Account;
import com.hhb.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
​
public class AccountDaoImpl implements AccountDao {
    @Override
    public Account selectByActno(String actno) {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        Account account = (Account) sqlSession.selectOne("account.selectByActno", actno);
        return account;
    }
​
    @Override
    public int updateByActno(Account account) {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        int count = sqlSession.update("account.updateByActno", account);
        return count;
    }
}

第七步:AccountDaoImpl中编写了mybatis代码,需要编写SQL映射文件

AccountMapper.xml

<?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="account">
    <select id="selectByActno" resultType="com.hhb.pojo.Account">
        select * from t_act where actno = #{actno}
    </select>
    <update id="updateByActno">
        update t_act set balance = #{balance} where actno = #{actno}
    </update>
</mapper>

第八步:编写AccountService接口以及AccountServiceImpl

MoneyNotEnoughException

package com.hhb.exceptions;
​
public class MoneyNotEnoughException extends Throwable {
    public MoneyNotEnoughException(){}
    public MoneyNotEnoughException(String msg){
        super(msg);
    }
}
 

TransferException

package com.hhb.exceptions;
​
/**
 * 转账异常
 */
public class TransferException extends Throwable {
    public TransferException(){}
    public TransferException(String msg){
        super(msg);
    }
}
​

AccountService

package com.hhb.service;
​
import com.hhb.exceptions.MoneyNotEnoughException;
import com.hhb.exceptions.TransferException;
​
import javax.xml.transform.TransformerException;
​
/**
 * 账户业务类
 */
public interface AccountService {
    /**
     * 账户转账业务
     * @param fromActno 转出账号
     * @param toActno 转入账号
     * @param money 转账金额
     */
    public void transfer(String fromActno,String toActno,double money) throws MoneyNotEnoughException, TransferException;
​
}

AccountServiceImpl

package com.hhb.service.impl;
​
​
import com.hhb.dao.AccountDao;
import com.hhb.dao.impl.AccountDaoImpl;
import com.hhb.exceptions.MoneyNotEnoughException;
import com.hhb.exceptions.TransferException;
import com.hhb.pojo.Account;
import com.hhb.service.AccountService;
import com.hhb.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
​
public class AccountServiceImpl implements AccountService {
​
    private AccountDao accountDao = new AccountDaoImpl();
​
    @Override
    public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, TransferException {
        //添加事务控制
        SqlSession sqlSession = SqlSessionUtil.openSession();
​
        //1.判断转出账户的余额是否充足(select)
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            //2.如果转出账户余额不足,提示用户
            throw new MoneyNotEnoughException("对不起,余额不足");
        }
        //3.如果转出账户余额充足,更新转出账户余额
        //先更新内存中的java对象account余额
        Account toAct = accountDao.selectByActno(toActno);
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);
        int count = accountDao.updateByActno(fromAct);
​
        //模拟异常
        //String s = null;
        //s.toString();
​
        //4.更新转入账户余额(update)
        count += accountDao.updateByActno(toAct);
        if (count != 2) {
            throw new TransferException("转账异常");
        }
​
        // 提交事务
        sqlSession.commit();
        // 关闭事务
        SqlSessionUtil.close(sqlSession);
    }
}
 

第九步:编写AccountServlet

package com.hhb.web;
​
import com.hhb.exceptions.MoneyNotEnoughException;
import com.hhb.exceptions.TransferException;
import com.hhb.service.AccountService;
import com.hhb.service.impl.AccountServiceImpl;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerException;
import java.io.IOException;
​
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet {
    private AccountService accountService = new AccountServiceImpl();
​
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        String moneyStr = request.getParameter("money");
        double money = Double.parseDouble(moneyStr);
​
        try {
            //调用service的转账方法完成转账
            this.accountService.transfer(fromActno, toActno, money);
            //调用view完成展示结果
            response.sendRedirect(request.getContextPath() + "/success.html");
        } catch (MoneyNotEnoughException e) {
            response.sendRedirect(request.getContextPath() + "/error1.html");
        } catch (TransferException e) {
            response.sendRedirect(request.getContextPath() + "/error2.html");
        } catch (Exception e){
            response.sendRedirect(request.getContextPath() + "/error2.html");
        }
    }
}
 

第十步:测试

  • 启动服务器,打开浏览器,输⼊地址:http://localhost:8080/bank,测试:

5.4MyBatis核心对象的作用域

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了SqlSessionFactory,就不再需要它了。

SqlSessionFactory

SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃他或重新创建另一个实例。使⽤ SqlSessionFactory 的最佳实践是在应⽤运⾏期间不要重复创建多次,多次重建 SqlSessionFactory被视为⼀种代码“坏习惯”。

SqlSession

每个线程都应该有它自己的SqlSession实例。SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。一般一个XxxxMapper.xml对应一个SqlSession对象。

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

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

相关文章

Istio 深入理解数据平面组件 Envoy

ingress control承载了控制面和数据面的一个职责&#xff0c;在control里面有一个process&#xff0c;这个进程就承担了反向代理的能力&#xff0c;当有任何请求发过来的时候&#xff0c;会被nginx接收到这个请求并且被转发&#xff0c;基于的规则由ingress control动态配置的&…

2023年7月1日【青书学堂】考试 计算机应用基础(高起专)

2023年7月1日【青书学堂】考试 计算机应用基础(高起专) 注意:答案仅供参考 成绩:88.8 分 第1题 单选题 在Word的编辑状态,按先后顺序依次打开了d1.doC、d2.doC、d3.doC、d4.doc 4个文档,当前的活动窗口的文档名为____。 A:d1.doc B:d2.doc C:d4.doc D:d3.doc 答案:C 第…

php代码还原工具,解决goto语句混淆,php goto解密还原

在编写php代码时&#xff0c;使用goto语句是一种常见的加密技巧。为了解决goto解码无法阅读这个问题&#xff0c;今天我要向大家介绍一款强大的php goto解密工具。 这款工具的主要功能之一就是php代码的还原。通过对代码进行解析和分析&#xff0c;它能够轻松还原被混淆的goto…

vim多文件切换快捷键设置

1、基本切换指令 vim中在打开多个文件时&#xff0c;会有多个文件进行切换的需求。按:bn切换到下一个文件&#xff0c;按:bp切换到上一个文件。 2、快捷键设置 为了便捷操作&#xff0c;将切换命令设置成快捷键。 进入/home/yys个人目录下&#xff0c;vim .vimrc进入vimrc文…

Spring Boot 中的 @EnableDiscoveryClient 注解

Spring Boot 中的 EnableDiscoveryClient 注解 Spring Boot 是一个快速开发 Spring 应用程序的框架&#xff0c;它提供了一些基础设施&#xff0c;使得我们可以快速地开发出高效、可靠的应用程序。其中&#xff0c;EnableDiscoveryClient 注解是 Spring Boot 中一个非常重要的…

C++刷题第四天 链表 24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 160. 链表相交 ● 142.环形链表II

24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例&#xff1a; 原列表为&#xff1a;1-2-3-4-…

【Mysql】Explain深入分析(三)

Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句&#xff0c;分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字&#xff0c;MySQL 会在查询上设置一个标记&#xff0c;执行查询会返回执行计划的信息&#xff0c;而不是执行这条SQL 注意…

node ffmpeg jsmpeg 拉流 展示笔记

拉流参考上一篇 基础&#xff1a;FFmpeg安装过 拉流完成之后转换成可播放的方式 1、下载jsmpeghttps://github.com/phoboslab/jsmpeg 下载完 用vscode 打开jsmpeg-master目录 2、在根目录下安装 node-media-server npm install node-media-server 新建app.js并运行 const…

8 图像去噪 滤波 锐化 边缘检测案例(matlab程序)

1.简述 学习目标&#xff1a;一个图像处理的经典综合案例 一、图像锐化的原理   图像锐化的目的是凸显物体的细节轮廓&#xff0c;通常可以用梯度、Laplace算子和高通滤波来实现&#xff0c;下面一一说明&#xff1a; 1、梯度法 梯度计算可以参考 小白学习图像处理——cann…

数据可视化01_t-SNE

1. t-SNE的定义 t-SNE stands for t-distributed Stochastic Neighbor Embedding. 代表 t 分布随机邻域嵌入。 t-SNE 获取高维数据并将其降低到较低维空间&#xff0c;同时保持数据点之间的关系尽可能接近其原始排列。 它是一种无监督机器学习算法&#xff0c;由 Laurens va…

8年测试经验总结,性能测试流程与性能测试学习路线,卷起来...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试流程 1、…

运输层概述、端口号、复用与分用

1.运输层概述、端口号、复用与分用 笔记来源&#xff1a; 湖科大教书匠&#xff1a;运输层概述 湖科大教书匠&#xff1a;运输层端口号、复用与分用的概念 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 1.1 运输层概述 计算机网络体系结构中的物…

交流220v转12v给单片机供电芯片

客户的应用需求&#xff1a;AD220V转DC12V 体积要非常小&#xff0c;单片机使用&#xff0c;单片机设备12V 电流很小不会超过100mA&#xff1f; 【AD220V转DC12V体积小的问题】 问题&#xff1a;我需要将交流电&#xff08;220V&#xff09;转换为直流电&#xff08;12V&…

fastadmin后台 点击开关 弹出 你没有权限访问 角色组里面添加了,除了超级管理员其他的只要用状态开关就,没权限 解决办法

首发地址&#xff1a;https://ask.fastadmin.net/question/22863.html 然后再对应的后台控制器里面 加入 protected $multiFields 你设计数据库的开关字段; //注意是字段&#xff0c;不是填写: multi 示例&#xff1a; protected $multiFields show_switch; 也可以多个 p…

QWebEngine应用(一)

前言 很早以前就听说过Qt也能显示网页&#xff0c;一直没有机会真正研究应用起来&#xff0c;刚好最近项目中使用到了QWebEngine内嵌浏览器打开第三方的网站&#xff0c;使用的Qt版本为5.15&#xff0c;踩了不少的坑&#xff0c;这里做个总结。 QWebEngine架构 Qt WebEngine…

亚马逊云科技连续12年被评为“领导者”,用实力赋能企业出海

从人类发展历史上看&#xff0c;无论是刳木为舟&#xff0c;剡木为楫&#xff0c;还是郑和下西洋&#xff0c;亦或是欧洲大航海时代&#xff0c;人类对于出海探索这件事就从未停止。而在如今的时代&#xff0c;相似的故事依旧在上演。过去的十年&#xff0c;是中国互联网最为繁…

多路码流RTSP传输并对每路视频图像叠加OSD信息

一、先保证多路视频码流保存到本地&#xff0c;并且分辨率正确 注意点&#xff1a; 1.VPSS分两路通道 2.VENC分两路通道 if(s32ChnNum>1) {s32Ret SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, enSize[0], &stSize);if (HI_SUCCESS ! s32Ret){SAMPLE_PRT("SAMPLE_COM…

下载网页视频的软件 下载网页视频的方法

视频已然成为一种非常有力的展示方式&#xff0c;我们想要下载视频内容&#xff0c;需要用到下载网页视频的软件&#xff0c;如今这类软件有很多。下载网页视频的方法&#xff0c;也因为使用的软件不同&#xff0c;方法各异。下面我们就来看详细介绍吧&#xff01; 一、下载网…

【DC-DC】AP9196 DC-DC升压恒流电源管理芯片 升降压3-12V输出9V LED驱动方案

1&#xff0c;方案;升降压3-12V输出9V LED驱动方案BOM表 ​ 2&#xff0c;方案;升降压3-12V输出9V LED驱动方案线路图 3&#xff0c;产品说明 AP9196 是一系列外围电路简洁的宽调光比升压调光恒流驱动器&#xff0c;适用于 3-40V 输入电压范围的 LED照明领域。AP9196 采用我…

Leveldb代码阅读笔记

整体架构 如上图&#xff0c;leveldb的数据存储在内存以及磁盘上&#xff0c;其中&#xff1a; memtable&#xff1a;存储在内存中的数据&#xff0c;使用skiplist实现。immutable memtable&#xff1a;与memtable一样&#xff0c;只不过这个memtable不能再进行修改&#xff0…