为什么互联网大厂都愿意用Mybatis?MyBatis缓存特性你了解吗?

无需 XML Mapper,超级 Mybatis 代码即是 SQL 操作!真香? 最近看到一个 ORM 框架 Fluent Mybatis 挺有意思的,整个设计理念非常符合工程师的思维。我对官方文档的部分内容进行了简单整理,通过这篇文章带你看看这个新晋 ORM 框架。官方文档: https://gitee.com/fluent-mybatis/fluent-mybatis/wikis提前声明一下:对于这类个人维护和开发的框架,如果大家没有充分的了解,一定一定一定不要用在正式的项目上!不然后续遇到问题会很麻烦的!!!我目前对于 Fluent Mybatis 这个框架也仅仅是感兴趣,想要学习 阅读详情

本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等

一、缓存简介

一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。

但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”引入了很多问题,比如缓存同步、缓存失效、缓存雪崩等等。当然这些问题不是本文讨论的重点。

本文主要讨论MyBatis缓存这个比较鸡肋的功能。虽然说MyBatis的缓存功能比较鸡肋,但是为了全面了解MyBatis这个框架,学习下缓存这个功能还是挺有必要的。MyBatis的缓存分为一级缓存和二级缓存,下面就分别来介绍下这两个特性。

二、一级缓存

在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

2.1 什么是MyBatis一级缓存

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


在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis 提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。

2.2 怎么开启一级缓存

MyBatis中一级缓存默认是开启的,不需要我们做额外的操作。

如果你需要关闭一级缓存的话,可以在Mapper映射文件中将flushCache属性设置为true,这种做法只会针对单个SQL操作生效

<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap" flushCache="true">
    select 
    <include refid="Base_Column_List" />
    from cbondissuer
    where OBJECT_ID = #{objectId,jdbcType=VARCHAR}
  </select>

还有一种做法是在MyBatis的主配置文件中,关闭所有的一级缓存

  默认是SESSION,也就是开启一级缓存
  <setting name="localCacheScope" value="STATEMENT"/>

下面我们来写代码验证下MyBatis的一级缓存。

String id = "123";
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
//同一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);
CbondissuerMapper cbondissuerMapper11 = sqlSession1.getMapper(CbondissuerMapper.class);
//另外一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper20 = sqlSession2.getMapper(CbondissuerMapper.class);

//同一个Mapper,同样的SQL查了两次
Cbondissuer cbondissuer10 = cbondissuerMapper10.selectByPrimaryKey(id);
Cbondissuer cbondissuer101 = cbondissuerMapper10.selectByPrimaryKey(id);
//同一个sqlSession创建的Mapper,又查询了一次同样的SQL
Cbondissuer cbondissuer11 = cbondissuerMapper11.selectByPrimaryKey(id);
//不一样的sqlSession创建的Mapper查询了一次同样的SQL
Cbondissuer cbondissuer20 = cbondissuerMapper20.selectByPrimaryKey(id);

System.out.println("cbondissuer10 equals cbondissuer101 :"+(cbondissuer10==cbondissuer101));
System.out.println("cbondissuer10 equals cbondissuer11 :"+(cbondissuer10==cbondissuer11));
System.out.println("cbondissuer10 equals cbondissuer21 :"+(cbondissuer10==cbondissuer20));

sqlSession1.close();
sqlSession2.close();
System.out.println("end...");

上面进行了四次查询,如果你观察日志的话。会发现只进行了两个数据库查询。因为第二和第三次的查询都查询了一级缓存,查出的其实是缓存中的结果。所以输出的结果是

cbondissuer10 equals cbondissuer101 :true
cbondissuer10 equals cbondissuer11 :true
cbondissuer10 equals cbondissuer21 :false

2.3 哪些因素会使一级缓存失效

上面的一级缓存初探让我们感受到了 MyBatis 中一级缓存的存在,那么现在你或许就会有疑问了,那么什么时候缓存失效呢?

  • 通过同一个SqlSession执行更新操作时,这个更新操作不仅仅指代update操作,还指插入和删除操作;
  • 事务提交时会删除一级缓存;
  • 事务回滚时也会删除一级缓存;

2.4 一级缓存源码解析

其实MyBatis一级缓存的实质就是一个Executor的一个类似Map的属性,分析源码的方法就是看在哪些地方从这个Map中查询了缓存,又是在哪些清空了这些缓存。

①. 查询时使用缓存分析

public abstract class BaseExecutor implements Executor {

  private static final Log log = LogFactory.getLog(BaseExecutor.class);

  protected Transaction transaction;
  protected Executor wrapper;

  protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
  //这个localCache变量就是一级缓存变量
  protected PerpetualCache localCache;
  protected PerpetualCache localOutputParameterCache;
  protected Configuration configuration;
  //..省略下面代码
}

全局搜索代码中哪些地方使用了这个变量,很容易找到BaseExecutor.query方法使用了这个缓存:

public abstract class BaseExecutor implements Executor {

// 省略其他代码
 public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List<E> list;
    try {
      queryStack++;
      //先从缓存中查询结果,如果缓存中已经存在结果直接使用缓存的结果
      list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
      if (list != null) {
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      } else {
        //缓存中没有结果从数据库查询
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    } finally {
      queryStack--;
    }
    if (queryStack == 0) {
      for (DeferredLoad deferredLoad : deferredLoads) {
        deferredLoad.load();
      }
      // issue #601
      deferredLoads.clear();
      if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        // issue #482
        clearLocalCache();
      }
    }
    return list;
  }
  //..省略下面代码
}

上面的代码展示了,BaseExecutor的query方法使用缓存的过程。需要注意的是查询缓存时是根据cacheKey进行查询的,我们可以将这个key简单的
理解为sql语句,不同的sql语句能查出不同的缓存。(注意sql语句中的参数不同也会被认为是不同的sql语句)。

②. 导致一级缓存失效的代码分析

查看BaseExecutor的代码,我们很容易发现是下面的方法清空了一级缓存。(不要问我是怎么发现这个代码的,看代码能力需要自己慢慢提升)

@Override
public void clearLocalCache() {
    if (!closed) {
        localCache.clear();
        localOutputParameterCache.clear();
    }
}

那么我们只要查看哪些地方调用了这个方法就知道哪些情况下会导致一级缓存失效了。跟踪下来,最后发现下面三处地方会使得一级缓存失效

BaseExecutor的update方法,使用MyBatis的接口进行增、删、改操作都会调用到这个方法,这个也印证了上面的说法。

@Override
  public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    clearLocalCache();
    return doUpdate(ms, parameter);
  }

BaseExecutor的commit方法,事务提交会导致一级缓存失败。如果我们使用Spring的话,一般事务都是自动提交的,所以好像MyBatis的一级缓存一直没怎么被考虑过

@Override
  public void commit(boolean required) throws SQLException {
    if (closed) {
      throw new ExecutorException("Cannot commit, transaction is already closed");
    }
    clearLocalCache();
    flushStatements();
    if (required) {
      transaction.commit();
    }
  }

BaseExecutor的rollback方法,事务回滚也会导致一级缓存失效。

@Override
  public void rollback(boolean required) throws SQLException {
    if (!closed) {
      try {
        clearLocalCache();
        flushStatements(true);
      } finally {
        if (required) {
          transaction.rollback();
        }
      }
    }
  }

2.5 一级缓存使用建议

平时使用MyBatis时都是和Spring结合使用的,在整个Spring容器中一般只有一个SqlSession实现类。而Spring一般都是主动提交事务的,所以说一级缓存经常失效。

还有就是我们也很少在一个事务范围内执行同一个SQL两遍,上面的这些原因导致我们在开发过程中很少注意到MyBatis一级缓存的存在。

不怎么用并不是说不用,作为一个合格的开发者需要对这些心知肚明,要清楚的知道MyBatis一级缓存的工作流程。

三、二级缓存

3.1 什么是MyBatis二级缓存

MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示:

当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个 共同的 cache(一个Mapper映射文件对应一个Cache),也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

从上面的图可以看出,MyBatis的二级缓存实现可以有很多种,可以是MemCache、Ehcache等。也可以是Redis等,但是需要额外的Jar包。

3.2 怎么开启二级缓存

二级缓存默认是不开启的,需要手动开启二级缓存,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。开启二级缓存的条件也是比较简单,

step1:通过直接在 MyBatis 配置文件中通过

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

step2: 在 Mapper 的xml 配置文件中加入 标签

cache标签下面有下面几种可选项

eviction: 缓存回收策略,支持的策略有下面几种

  • LRU - 最近最少回收,移除最长时间不被使用的对象(默认是这个策略)
  • FIFO - 先进先出,按照缓存进入的顺序来移除它们
  • SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象
  • WEAK - 弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象

flushinterval:缓存刷新间隔,缓存多长时间刷新一次,默认不清空,设置一个毫秒值;

readOnly: 是否只读;true 只读 ,MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。MyBatis 为了加快获取数据,直接就会将数据在缓存中的引用交给用户。不安全,速度快。读写(默认):MyBatis 觉得数据可能会被修改

size: 缓存存放多少个元素

type: 指定自定义缓存的全类名(实现Cache 接口即可)

blocking:若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。

3.3 哪些因素会使二级缓存失效

从上面的介绍可以知道MyBatis的二级缓存主要是为了SqlSession之间共享缓存设计的。但是我们平时开发过程中都是结合Spring来进行MyBatis的开发。在Spring环境下一般也只有一个SqlSession实例,所以二级缓存使用到的机会不多。所以下面就简单描述下Mybatis的二级缓存。

还是以上面的列子为列

String id = "{0003CCCA-AEA9-4A1E-A3CC-06D884BA3906}";
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
//同一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);
CbondissuerMapper cbondissuerMapper11 = sqlSession1.getMapper(CbondissuerMapper.class);
//另外一个sqlSession创建的Mapper
CbondissuerMapper cbondissuerMapper20 = sqlSession2.getMapper(CbondissuerMapper.class);

//同一个Mapper,同样的SQL查了两次
Cbondissuer cbondissuer10 = cbondissuerMapper10.selectByPrimaryKey(id);
Cbondissuer cbondissuer101 = cbondissuerMapper10.selectByPrimaryKey(id);
//同一个sqlSession创建的Mapper,又查询了一次同样的SQL
Cbondissuer cbondissuer11 = cbondissuerMapper11.selectByPrimaryKey(id);
//这边需要提交事务才能让二级缓存生效
sqlSession1.commit();
//不一样的sqlSession创建的Mapper查询了一次同样的SQL
Cbondissuer cbondissuer20 = cbondissuerMapper20.selectByPrimaryKey(id);

System.out.println("cbondissuer10 equals cbondissuer101 :"+(cbondissuer10==cbondissuer101));
System.out.println("cbondissuer10 equals cbondissuer11 :"+(cbondissuer10==cbondissuer11));
System.out.println("cbondissuer10 equals cbondissuer21 :"+(cbondissuer10==cbondissuer20));
  • 二级缓存是以namespace(Mapper)为单位的,不同namespace下的操作互不影响。
  • insert,update,delete操作会清空所在namespace下的全部缓存。
  • 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

3.4 二级缓存使用建议

个人觉得MyBatis的二级缓存实用性不是很大。一个原因就是Spring环境下,一本只有一个SqlSession,不存在sqlSession之间共享缓存;还有就是MyBatis的缓存都不能做到分布式,所以对于MyBatis的二级缓存以了解为主。

四、简单总结

4.1 一级缓存

  • 一级缓存的本质是Executor的一个类似Map的属性;
  • 一级缓存默认开启,将flushCache设置成true或者将全局配置localCacheScope设置成Statement可以关闭一级缓存;
  • 在一级缓存开启的情况下,查询操作会先查询一级缓存,再查询数据库;
  • 增删改操作和事务提交回滚操作会导致一级缓存失效;
  • 由于Spring中事务是自动提交的,因此Spring下的MyBatis一级缓存经常失效。(但是并不表示不生效,除非你手动关闭一级缓存)
  • 不能实现分布式。

4.2 二级缓存

  • namesapce级别的缓存(Mapper级别或者叫做表级别的缓存),设计的主要目的是实现sqlSession之间的缓存共享;
  • 开启二级缓存后,查询的逻辑是二级缓存->已经缓存->数据库;
  • insert,update,delete操作会清空所在namespace下的全部缓存;
  • 多表查询一定不要使用二级缓存,因为多表操作进行更新操作,可能会产生脏数据。
  • 总体来说,MyBatis的缓存功能比较鸡肋。想要使用缓存的话还是建议使用spring-cache等框架。
互联网大厂Java面试揭秘:从Spring到微服务的全面技术探讨 面试官我们会在一周内给你答复,请回去等通知。 阅读详情

相关推荐

osg3.6.5---osgEarth3.2 实现数字地球的加载

目前我在网上找得比较多的是osgearth2.10及以下的版本及加载数字地球的方法,但是我使用的是osg3.6.5和osgEarth3.。但是3.x版本和2.x版本差别很大,主要区别在于2.x有7个主要库,而3.x版本只有osgEarth这一个库。所以,特别记录一下。后面我讲他集成到qt的窗体在上传更新新的代码。1.直接上源码pro文件和cpp文件。

枫影竹韵的博客 1008

揭秘MyBatis为什么在阿里等大厂这么流行

什么是Mybatis?众所周知,MyBatis 是一款非常优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。不仅避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。...

全栈开发者社区 840

【音视频处理】MP4、FLV、HLS适用范围,在线视频播放哪个更好

本期我们讨论在线点播的视频格式,对比这些视频格式的优劣以及原因 1、封装格式的作用 2、MP4 3、FLV 4、HLS

池鱼 - YiiGaa 2万+

MyBatis一级缓存的笔记及记录

一、概述:   一级缓存是MyBatis天然自带的,是默认开启且没有关闭的地方,1级缓存只能作用于查询回话中,所以也叫会话缓存; 这里举个例子:   订单表存在一对多的关系,为了尽可能的减少join的查询,进行了分阶段查询; 先查询出订单表,在根据订单的用户ID查询用户信息表,最后将数据进行整合。如果订单表中存在重复的用户ID,就会出现很多没有必要的重复查询。 1级缓存解决了这个问题(1个语...

hys8298的博客 149

跟着团子学SAP CO:熟练使用结果分析码实现各个场景下收入成本的匹配(一) KKA2/CJ88

PS模块中对财务顾问最难的点在于项目结算,特别是销售型的项目结算。针对客户型项目结算我列举了以下常见的收入成本匹配的一些场景: (1)在项目执行过程中会多次开票,但由于各期成本浮动很大(如前期可能只涉及一些人工、中期全是比较金额较大的材料费),所以希望开票的时候能通过合理的一些指标进行主营业务成本与主营业务收入的匹配。 (2)项目过程中会多次开票,开票确认主营业务收入时,直接将累计发生的实际成本结转为主营业务成本。 (3)项目过程中虽多次开票,但不确认收入,所有发生的实际成本月末计算为在制品,最后项目一次性

Lucas1211的博客 9534

RT-Thread实战:手把手教你用STM32F04ZGT6通过SPI驱动BMI088(附完整工程)

本文详细介绍了如何使用RT-Thread操作系统在STM32F04ZGT6上通过SPI接口驱动BMI088高性能6轴惯性传感器(包含陀螺仪和加速度计)。从硬件连接到软件配置,再到数据采集与处理,提供了完整的开发指南和优化技巧,帮助开发者快速实现精确的姿态测量功能。

kappa的博客 236

再见MybatisPlus,阿里推出新ORM框架!

juejin.cn/post/6886019929519177735使用fluent mybatis也可以不用写具体的 xml 文件,通过 java api 可以构造出比较复杂的业务 sq...

码农code之路 1267

从GAN生成失败案例出发:为什么你的AI画不准位置?CoordConv保姆级解决方案

本文深入探讨了GAN生成图像时位置偏移问题的根源,并提供了CoordConv的保姆级解决方案。通过分析传统CNN在空间坐标建模上的缺陷,详细介绍了CoordConv的原理、实现步骤及在StyleGAN2等模型中的实战应用,显著提升了医学图像生成等任务的定位精度。

pp12345的博客 204

为什么mybatiseplus这么好用,反而用的不多?

通俗易懂,深入浅出,多个角度分析也许让你眼前一亮。

java架构师进阶之路的博客 5592

四旋翼无人机数学模型推导

本周开始进行四旋翼无人机的学习工作,首先来进行四旋翼无人机的数学模型推导工作。。 四旋翼动力学数学模型 坐标变换 介绍四旋翼数学模型之前,首先引入坐标变换的概念,定义两个坐标系惯性坐标系{E},以及机体坐标系{B},惯性坐标系就相当于在地面建立的、静止不动的坐标系,也是我们操纵无人机所在的空间,而机体坐标系是建立于四旋翼机体之上,随着四旋翼姿态变换而变化,所以建立一种地面上的惯性坐标系与四旋翼机体坐标系之间的转换关系,就有这个必要。 对于惯性坐标系{E},以及机体坐标系{B},它们之间的转换关系

BiuBiuSun的博客 1万+

用Python手把手教你实现一个多层感知机(MLP)——从理论到代码实战

本文详细介绍了如何使用Python和Theano库从零开始实现多层感知机(MLP),涵盖从核心原理到代码实战的全过程。通过构建隐藏层、输出层和完整MLP模型,结合权重初始化、激活函数选择和训练技巧,帮助开发者深入理解神经网络工作机制,并应用于实际机器学习任务。

web39explorer的博客 970

为什么互联网大厂都愿意用 Mybatis? MyBatis 缓存特性你了解吗?

一、缓存简介 一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。 但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”引入了很多问题,比如缓存同步、缓存失效、缓存雪崩等等。当然这些问题不是本文讨论的重点。 本文主要讨论 MyBatis 缓存这个比较鸡肋的功能。虽然说 MyBatis 的缓存功能比较鸡肋,但是为了全

qq_42986622的博客 1635

Linux ARM平台开发系列讲解(摄像头V4L2子系统) 2.12.7 摄像头V4L2驱动开发流程总结

1.概述前几章对摄像头V4L2驱动开发各个环节做了展开分析,这一章节就做一个汇总,用来回顾前几章得知识点,概括一下摄像头开发得流程,本次使用RK3399。2.SensorSub-device开发移植Sensor驱动位于目录下,注意到本章节所描述的是具有属性的sensor驱动,故目录下的驱动并不适用。在结构下,Sensor一般作为sub-device并通过pad与cif、isp或者mipiphy链接在一起。本章主要介绍Sensor驱动的代码[1],dts配置,及如何验证sensor5个部分。...

DSMGUOGUO的博客 3729

mybatis update不生效_为什么互联网大厂都愿意用Mybatis?MyBatis缓存特性你了解吗?...

本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等一、缓存简介一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”引入了很多问题,比如缓...

weixin_39915427的博客 127

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

2025互联网大厂高频Java面试真题解析

不知道最近大家面试是否顺利,是否会经常也会被问到一些自己不熟悉的问题,不知道怎么去回答这些问题,今天笔者给大家整理了 2025 年牛客网上的一些面试真题及解析,内容点包含有 java 集合,,网络,,readis 缓存,数据库,设计模式 等一线大厂互联网大厂常问到的面试真题。

m0_69632475的博客 874

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

互联网大厂Java求职者面试实战(Spring Boot, Mybatis)

作为一名希望进入互联网大厂的Java工程师,面试时经常会被问及Spring Boot、Mybatis、分页实现、性能调优、事务管理和微服务架构相关技术。本文将通过模拟面试情境,从实战问题出发,详细探讨这些核心技术点,帮助大家更加系统、深入地理解与掌握。面试问题:请简述Spring Boot项目的启动流程及核心机制。答题要点:面试问题:Mybatis是如何完成数据库操作的?其核心原理是什么?答题要点:面试问题:通常在实际开发中,如何对查询结果进行分页?请举例说明。答题要点:代码示例: 五、性能调优 面试问题:

2502_91315076的博客 1447

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

这可能是把MyBatis缓存特性讲的最清楚的一篇文章了

最新互联网大厂面试真题、Java程序员面试策略(面试前的准备、面试中的技巧)请移步GitHub 一、缓存简介 一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。 但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”引入了很多问题,比如缓存同步、缓存失效、缓存雪崩等等。当然这些问题不是本文讨论的重点。 本文主要讨论My

Java_Cappuccino的博客 199

互联网大厂Java面试实录:Stream、缓存策略、Kafka顺序性等核心技术深度详解

在互联网大厂的严苛岗位面试中,技术的深度与场景的复杂性往往决定了最终能否成功。本文以程序员谢飞机为主角,展现他与面试官的真实对话和技术碰撞,通过3轮提问层层递进,涵盖Java核心、Spring、分布式微服务等关键技术点。文末附详细答案解析,便于Java初学者理解提升。

2303_82092544的博客 590

mybatis同一个sql执行多次出现重复数据_这可能是把MyBatis缓存特性讲的最清楚的一篇文章了...

最新互联网大厂面试真题、Java程序员面试策略(面试前的准备、面试中的技巧)请移步GitHub一、缓存简介一般我们在系统中使用缓存技术是为了提升数据查询的效率。当我们从数据库中查询到一批数据后将其放入到混存中(简单理解就是一块内存区域),下次再查询相同数据的时候就直接从缓存中获取数据就行了。这样少了一步和数据库的交互,可以提升查询的效率。但是一个硬币都具有两面性,缓存在带来性能提升的同时也“悄悄”...

weixin_39715187的博客 1842

互联网大厂高频面试专题 500 道:并发编程 /Spring/MyBatis(附答案解析)

后面还有关于 springMVC,微服务,Dubbo,netty,网络,zookeeper,kafka,rabbitMQ,readis 缓存,数据库,设计模式,就不在这里一一给大家展示了。

sjkflw121150的博客 870

互联网大厂Java求职面试全景解析:Spring Boot、微服务与缓存技术实战

本文通过严肃面试官与搞笑程序员的对话场景,逐步展开互联网大厂Java求职面试的多轮提问,涵盖主流技术栈,详解答案及业务应用,帮助小白快速掌握面试关键技术。

weixin_51741939的博客 238

Java面试实战:互联网大厂求职指南

在一个阳光明媚的早晨,谢飞机怀着忐忑的心情走进了一家知名互联网大厂的面试室。面试官是一位严肃的技术主管,打算从Java技术栈的各个方面对谢飞机进行考核。

m0_55712218的博客 598

互联网大厂Java面试实录:面试官与程序员张三的爆笑对话

某互联网大厂的Java面试现场,面试官严肃冷静,程序员张三略带戏谑。在三轮技术问答中,面试官步步为营,涵盖Java核心、JUC、JVM、Spring、MyBatis、Dubbo、数据库、消息队列等各类主流技术。张三遇到简单问题能应付自如,遇到难题则胡乱作答,场面极具喜感。

qq_41780196的博客 1489

互联网大厂Java面试实战:谢飞机的搞笑回答与深度技术解析

自动配置:根据类路径上的依赖自动配置Spring应用,减少手动配置。起步依赖:提供了一组默认的依赖关系,开发者只需引入即可快速启动项目。Actuator:提供生产级的监控功能,如健康检查、指标收集等。

qq_54002085的博客 936
上一篇: 如何做好容器化管理?腾讯架构师一篇文章带你吃透 Docker 原理
下一篇: 面试官:String是值传递还是引用传递
Java_Cappuccino
博客等级 码龄7年 17粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值