【MyBatis缓存机制深度解析】:掌握一级缓存与二级缓存的底层原理与最佳实践

深入理解MyBatis的一级缓存和二级缓存机制 在现代Java企业级应用开发中,MyBatis作为一款优秀的持久层框架,因其灵活性和高性能而广受欢迎。缓存作为提升数据库访问性能的关键技术,在MyBatis中有着精妙的实现。本文将全面剖析MyBatis的一级缓存和二级缓存机制,从基础概念到高级应用,帮助开发者深入理解并合理运用MyBatis缓存来优化应用性能。 阅读详情

第一章:MyBatis缓存机制概述

MyBatis 作为一款优秀的持久层框架,提供了强大的 SQL 映射与对象关系映射能力,其中缓存机制是提升数据库操作性能的关键组成部分。通过合理利用缓存,可以有效减少对数据库的重复查询,降低系统负载,提高响应速度。

缓存的基本分类

MyBatis 的缓存体系主要分为两种类型:
  • 一级缓存(Local Cache):默认开启,作用范围为 SqlSession 级别。在同一个 SqlSession 中执行相同 SQL 查询时,会从缓存中直接返回结果。
  • 二级缓存(Second Level Cache):跨 SqlSession 生效,通常作用于同一个 Mapper Namespace 下。需手动开启,并要求返回结果对象实现 Serializable 接口。

缓存的工作流程

当执行查询操作时,MyBatis 按照以下顺序获取数据:
  1. 首先检查二级缓存中是否存在对应数据(若启用);
  2. 若未命中,则查看当前 SqlSession 的一级缓存;
  3. 若两级缓存均未命中,则访问数据库并加载数据;
  4. 将查询结果写入一级缓存,若配置了二级缓存且符合条件,则同步到二级缓存。

二级缓存配置示例

要在 MyBatis 中启用二级缓存,需在 Mapper XML 文件中添加 <cache/> 标签:
<!-- 开启当前命名空间的二级缓存 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
上述配置说明:
  • eviction="LRU":使用最近最少使用算法清理缓存;
  • flushInterval="60000":每隔 60 秒刷新一次缓存;
  • size="512":最多缓存 512 个查询结果;
  • readOnly="true":表示返回的对象是只读的,可提升性能。

缓存策略对比

特性一级缓存二级缓存
作用范围SqlSession 级别Mapper Namespace 级别
默认状态开启关闭
数据共享不跨 SqlSession多个 SqlSession 可共享

第二章:一级缓存的底层原理与应用实践

2.1 一级缓存的作用域与生命周期解析

作用域边界界定
MyBatis 的一级缓存默认开启,其作用域为 SqlSession 级别。同一个会话中执行相同 SQL 查询时,会直接从缓存获取结果,避免重复数据库访问。
生命周期同步机制
缓存的生命周期与 SqlSession 完全一致:在会话创建时诞生,关闭或清空时销毁。任何增删改操作都会清空缓存,确保数据一致性。
  • 缓存基于 HashMap 实现,键为查询条件组合
  • 事务提交或回滚将触发缓存清理
SqlSession session = sqlSessionFactory.openSession();
User user = session.selectOne("selectUser", 1); // 查询走缓存
session.update("updateUser", user);             // 更新后缓存被清空
上述代码中,update 操作自动清空缓存,后续相同查询将重新访问数据库。

2.2 SqlSession级别缓存的执行流程剖析

SqlSession级别的缓存是MyBatis的一级缓存,默认开启,作用域为同一个SqlSession内。当执行查询时,MyBatis会将查询结果存储在SqlSession的本地缓存中。
缓存命中流程
  1. 用户发起SQL查询请求
  2. MyBatis检查当前SqlSession缓存中是否存在相同语句和参数的缓存记录
  3. 若存在,则直接返回缓存结果;否则执行数据库查询并缓存结果

// 示例:SqlSession缓存行为
SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("selectUserById", 1); // 查询数据库,写入缓存
User user2 = session.selectOne("selectUserById", 1); // 直接从缓存获取
上述代码中,第二次查询不会访问数据库,而是直接从SqlSession的HashMap结构中获取结果。缓存底层基于一个简单的PerpetualCache实现,以MappedStatement的ID和查询参数作为缓存键。
缓存失效机制
任何增删改操作(INSERT、UPDATE、DELETE)都会清空一级缓存,确保数据一致性。调用session.clearCache()也会手动清除缓存。

2.3 一级缓存命中条件与失效场景分析

缓存命中的核心条件
一级缓存(如MyBatis中SqlSession级别的缓存)命中需满足:相同的SqlSession、相同的SQL语句、相同的参数值、相同的执行环境。只有当这些条件全部匹配时,系统才会直接返回缓存结果。
常见失效场景
  • 执行任何增删改操作后,缓存自动清空
  • 手动调用clearCache()方法
  • SqlSession关闭或提交事务
  • 查询条件发生变更,导致缓存键不一致
sqlSession.selectList("getUserById", 1);
// 此时触发数据库查询并写入缓存

sqlSession.update("updateUser", user); 
// 执行更新操作,一级缓存被清空
上述代码中,执行update操作后,所有已缓存的查询将失效,后续相同查询需重新访问数据库。

2.4 通过源码追踪一级缓存的实现机制

在 MyBatis 的执行流程中,一级缓存默认开启,其核心实现在 BaseExecutor 类中。缓存对象本质是一个 PerpetualCache 实例,以 HashMap 结构存储查询结果。
缓存的存储结构
protected PerpetualCache localCache;

public class PerpetualCache implements Cache {
    private final Map<Object, Object> cache = new HashMap<>();
}
该缓存以 CacheKey 为键,查询结果为值。每次执行查询前,先调用 localCache.getObject(key) 尝试命中缓存。
关键触发时机
  • 执行 query() 方法时检查缓存
  • 执行 commit() 或 rollback() 时清空缓存
  • 同一 SqlSession 内重复查询可命中缓存
一级缓存生命周期与 SqlSession 绑定,无法跨会话共享。

2.5 一级缓存使用中的常见问题与规避策略

缓存穿透
当查询不存在的数据时,缓存层无法命中,请求直接打到数据库,高并发下可能导致数据库压力激增。可通过布隆过滤器提前拦截无效请求。

// 使用布隆过滤器判断键是否存在
if !bloomFilter.MayContain(key) {
    return ErrKeyNotFound
}
data, _ := cache.Get(key)
上述代码中,bloomFilter.MayContain 可快速排除无效键,避免缓存与数据库的无谓查询。
缓存雪崩
大量缓存同时过期,导致瞬时请求涌向后端存储。应采用错峰过期策略:
  • 设置随机 TTL,如基础时间 + 随机分钟
  • 引入二级缓存或本地缓存作为兜底

第三章:二级缓存架构设计与核心组件

3.1 二级缓存的整体工作原理与启用条件

工作原理概述
MyBatis 的二级缓存是跨 SqlSession 的缓存机制,绑定在 Mapper 命名空间级别。当多个 SqlSession 执行相同命名空间下的查询时,结果会被缓存到 Cache 实例中,后续请求直接从缓存获取。
启用条件
  • 全局配置中开启 cacheEnabled(默认开启)
  • 在 Mapper XML 中声明 <cache/>
  • 查询的 POJO 必须实现 Serializable 接口
  • 执行的所有 SQL 操作必须在同一个命名空间下
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
上述配置定义了缓存策略:使用 LRU 算法回收,每 60 秒清空一次,最多缓存 512 个对象,且返回只读对象以提升性能。
数据同步机制
当执行 insert、update 或 delete 操作时,MyBatis 会自动清空对应命名空间的缓存,确保数据一致性。

3.2 Cache接口与标准实现类的功能解析

Cache接口定义了缓存操作的核心契约,包括数据的存取、删除与过期策略。其标准实现类如`ConcurrentMapCache`和`EhCacheCache`分别基于内存结构与第三方库提供具体支持。
核心方法定义
接口中关键方法包括:
  • get(Object key):根据键获取缓存值
  • put(Object key, Object value):写入缓存项
  • evict(Object key):移除指定条目
典型实现分析
public class ConcurrentMapCache implements Cache {
    private final ConcurrentMap<Object, Object> store = new ConcurrentHashMap<>();
    
    @Override
    public ValueWrapper get(Object key) {
        return new SimpleValueWrapper(store.get(key));
    }
}
上述代码展示基于ConcurrentHashMap的线程安全缓存实现,适用于单机高并发场景,但不具备分布式能力。

3.3 缓存装饰器模式在二级缓存中的应用

缓存装饰器模式通过封装基础缓存操作,为二级缓存(如本地+分布式缓存)提供统一访问接口,提升代码可维护性与性能。
设计结构与职责分离
装饰器将本地缓存(如 Caffeine)作为一级缓存,Redis 作为二级缓存,请求优先命中本地,未命中则查询远程并回填。
代码实现示例

@Cacheable(name = "user", local = true, ttl = 60)
public User findUser(Long id) {
    return userRepository.findById(id);
}
上述注解表示启用双层缓存机制:`local=true` 启用本地缓存,`ttl=60` 设置过期时间为60秒。方法执行前自动检查两级缓存,避免重复加载。
  • 第一层:检查本地缓存是否存在,存在则直接返回
  • 第二层:本地未命中,查询 Redis 缓存
  • 第三层:均未命中,访问数据库并异步写入两级缓存
该模式显著降低数据库压力,同时减少网络延迟对响应时间的影响。

第四章:二级缓存的配置与最佳实践

4.1 开启二级缓存的XML配置与注解方式

在 MyBatis 中,二级缓存能显著提升查询性能。可通过 XML 配置或注解两种方式开启。
XML 配置方式
在映射文件中添加 <cache/> 标签即可启用二级缓存:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
其中,eviction 指定回收策略,flushInterval 设置刷新间隔(毫秒),size 限制缓存条目数,readOnly 控制是否只读。
注解方式
使用 @CacheNamespace 注解在接口上开启缓存:
@CacheNamespace(readOnly = false, eviction = LruCache.class)
该方式适用于注解驱动的开发场景,灵活性更高,支持自定义缓存实现。 两种方式均需确保 SqlSession 提交后缓存才生效,且实体类实现 Serializable 接口。

4.2 自定义缓存实现与第三方缓存集成(如Redis)

在构建高性能应用时,自定义缓存可针对特定业务场景优化数据访问效率。通过实现简单的内存缓存结构,结合接口抽象,可灵活切换底层存储机制。
基础自定义缓存实现
type Cache interface {
    Set(key string, value interface{})
    Get(key string) (interface{}, bool)
}

type InMemoryCache struct {
    data map[string]interface{}
}

func (c *InMemoryCache) Set(key string, value interface{}) {
    c.data[key] = value
}

func (c *InMemoryCache) Get(key string) (interface{}, bool) {
    val, exists := c.data[key]
    return val, exists
}
上述代码定义了一个基于哈希表的内存缓存,支持基本的读写操作。Set 方法存储键值对,Get 返回值及存在状态,适用于低频更新场景。
集成 Redis 作为分布式缓存
使用 go-redis 驱动可无缝替换本地缓存:
  • 统一 Cache 接口便于依赖注入
  • Redis 提供持久化、过期策略和集群支持
  • 提升系统横向扩展能力

4.3 并发访问下的缓存一致性保障策略

在高并发系统中,多个客户端或服务实例同时操作缓存与数据库时,极易引发数据不一致问题。为确保数据最终一致性,需引入合理的同步机制与更新策略。
写穿透与双写一致性
采用“先更新数据库,再失效缓存”(Write-Through + Cache Invalidation)模式可有效减少脏读。典型实现如下:

func UpdateUser(id int, name string) error {
    // 1. 更新数据库
    if err := db.Exec("UPDATE users SET name = ? WHERE id = ?", name, id); err != nil {
        return err
    }
    // 2. 删除缓存,触发下次读取时重建
    redis.Del(fmt.Sprintf("user:%d", id))
    return nil
}
该逻辑确保数据源权威性,通过删除而非更新缓存,避免并发写导致的状态冲突。
并发控制与版本校验
引入Redis分布式锁与版本号机制,防止并发写覆盖:
  • 使用SETNX加锁,保证更新临界区互斥
  • 为缓存数据附加版本戳(如timestamp或自增ID)
  • 读取时校验版本,过期则主动刷新缓存
此策略显著降低多实例场景下缓存状态分裂风险。

4.4 二级缓存性能优化与使用场景建议

在高并发系统中,合理利用二级缓存可显著降低数据库负载。通过引入分布式缓存如 Redis 或 Memcached,多个应用实例可共享缓存数据,避免重复查询。
缓存更新策略
推荐采用“写穿透 + 失效”模式:当数据更新时,先更新数据库,再使缓存失效,由下一次读请求重建缓存。

// 示例:缓存失效逻辑
public void updateUser(User user) {
    userRepository.update(user);
    redisCache.delete("user:" + user.getId()); // 删除旧缓存
}
该方式保证数据最终一致性,适用于读多写少场景。
适用场景对比
场景是否推荐说明
用户资料查询推荐读频繁,数据变更少
订单状态更新谨慎使用需强一致性,建议结合消息队列同步缓存

第五章:总结与缓存使用全景回顾

缓存策略的实战选择
在高并发系统中,合理选择缓存策略直接影响响应延迟与数据库负载。常见的策略包括 Cache-Aside、Read/Write Through 和 Write Behind。例如,在用户资料服务中采用 Cache-Aside 模式,可显著降低 MySQL 查询压力:
// Go 中实现 Cache-Aside 示例
func GetUser(id int) (*User, error) {
    var user User
    // 先查 Redis
    if err := cache.Get(fmt.Sprintf("user:%d", id), &user); err == nil {
        return &user, nil
    }
    // 回源查 DB
    if err := db.QueryRow("SELECT name, email FROM users WHERE id = ?", id).Scan(&user.Name, &user.Email); err != nil {
        return nil, err
    }
    // 异步写入缓存,设置 TTL 避免雪崩
    go cache.Set(fmt.Sprintf("user:%d", id), user, 30*time.Minute)
    return &user, nil
}
多级缓存架构的应用场景
大型系统常采用本地缓存 + 分布式缓存的多级结构。例如,电商商品详情页使用 Caffeine 作为一级缓存,Redis 作为二级,有效降低跨网络调用频率。
  • 本地缓存适用于访问频繁且容忍短暂不一致的数据
  • 分布式缓存保障多实例间数据共享与一致性
  • 需配置合理的失效机制,避免脏数据累积
缓存异常问题的应对方案
面对缓存穿透、击穿与雪崩,应结合实际场景部署防御措施。如使用布隆过滤器拦截无效请求,或为关键 Key 设置逻辑过期:
问题类型解决方案案例
缓存穿透布隆过滤器 + 空值缓存防止恶意查询不存在的商品 ID
缓存雪崩随机 TTL + 高可用集群大批 Key 同时过期导致 DB 崩溃
MySQL8.2.0下载安装 4、点击No thanks,just start my download,就是只是开始下载的意思,点击下载,等待下载完成。5、新建空白行,或直接双击紧挨的空白行,把复制的mysql的安装路径bin路径复制粘贴过来,确定,确定,确定。1、上面点击finish后,自动勾选了run mysql配置,自动会打开配置页面,点击Next。1、双击安装包,进入安装流程,勾选我同意 I accept,next。2、根据自己需要选择,我选的第二个,可以自己改安装路径。2、默认,点击Next,记住默认端口3306。 阅读详情

相关推荐

UE5实战技巧:TextRender高效集成中文字体与材质优化

本文针对UE5中TextRender组件显示中文的常见问题,提供了一套完整的实战解决方案。详细讲解了如何通过手动创建字体资产、精准控制字符集来优化性能,并重点介绍了通过调整材质中的Lerp节点参数(如设为-85, 92)来解决中文字体显示残缺和边缘模糊等核心难题,帮助开发者实现高效且美观的中文文本渲染。

weixin_28040125的博客 380

MyBatis缓存实战指南:一级与二级缓存的深度解析与性能优化

在电商大促期间,我们的用户查询接口QPS从500骤增至5000,数据库连接池频频告警。当我将MyBatis二级缓存应用在用户基础信息模块后,数据库负载直接下降70%——这就是缓存的力量。

DD2187718660的博客 2740

【TensorRT】TensorRT C# API 项目介绍:基于C#与TensorRT部署深度学习模型(上篇)

开发了TensorRT C# API 2.0版本,该版本在开发时充分考虑了上一版本应用时出现的问题,并进行了改进。同时在本版本中,我们对接口进行了优化,使用起来更加简单,并同时提供了相关的应用案例,方便开发者进行使用。

grape_yan的博客 3038

【Mybatis】说一下 mybatis 的一级缓存和二级缓存

在数据库访问中,性能优化一直是开发者关注的焦点之一。MyBatis 作为一种流行的持久层框架,提供了一级缓存和二级缓存两种缓存机制,以帮助开发者提高数据库查询效率。本文将深入探讨 MyBatis 中的一级缓存和二级缓存的原理、使用方式以及适用场景,帮助开发者更好地理解和应用缓存机制。缓存机制在数据库访问中扮演了至关重要的角色,MyBatis 的一级缓存和二级缓存为我们提供了灵活且可控的缓存解决方案。

AliceNo的博客 3293

从零开始搭建水质监测系统:STM32+Lora+4G的物联网应用详解

本文详细介绍了如何从零开始搭建一个基于STM32、LoRa和4G技术的工业级水质监测物联网系统。文章深入剖析了系统架构设计、核心硬件选型(如STM32F103系列MCU)、关键电路接口、嵌入式软件驱动开发、多任务调度以及云端数据集成与可视化的完整实战流程,为智慧农业、环境监测等领域的物联网应用提供了宝贵的“避坑指南”和解决方案。

m0n1o2p的博客 583

基于Flink的流式数据降维实现方案

理解为何实时场景需要降维(解决维度灾难)掌握Flink流处理与降维算法的结合方式学会用Flink实现一个可落地的流式降维系统覆盖内容包括:Flink流处理基础、降维算法选择(侧重在线算法)、Flink与降维的集成方案、实战代码示例,以及工业级场景的应用经验。本文从“为什么需要流式降维”出发,用“快递分拣”的生活案例引出核心概念;接着拆解Flink流处理、数据降维的底层逻辑;然后重点讲解“在线PCA”这一适合流式场景的降维算法,并用Flink实现一个完整的流式降维管道;

AI 领航者的博客 567

MyBatis缓存机制:一级与二级缓存详解

一级缓存与二级缓存的原理与实战 MyBatis提供两级缓存优化查询性能:一级缓存为SqlSession级别,默认开启,仅在单次会话内有效;二级缓存为Mapper级别,需手动配置,支持跨会话共享。一级缓存通过LocalCache实现,写操作会自动清空;二级缓存要求实体类序列化,通过Cache接口实现,写操作会清空当前Mapper缓存。本文详细分析了两级缓存的工作原理、配置方法、使用场景及优化技巧,包括缓存失效场景、序列化要求、分布式缓存集成方案等,帮助开发者合理运用缓存提升系统

2401_83675559的博客 1365

ZYNQ 7020 之 FPGA知识点重塑笔记一——串口通信

通信方式一般分为串行通信和并行通信。并行通信是指多比特数据同时通过并行线进行传送。这种传输方式通信线多、成本高,故不宜进行远距离通信,通常传输距离小于 30 米。串行通信是指数据在一条数据线上,一比特接一比特地按顺序传送的方式。这种运输方式通常节省传输线,大大降低使用成本,但数据传送速度慢。综上可知,串行通信主要应用于长距离、低速率的通信场合。本次实验我们主要讲解下串行通信。串行通信一般有2种通信方式:同步串行通信和异步串行通信。同步串行通信。

m0_51430584的博客 3094

MyBatis 缓存机制源码深度解析:一级缓存与二级缓存

本文深入解析MyBatis缓存机制,剖析一级缓存和二级缓存的实现原理与差异。一级缓存是会话级缓存,基于BaseExecutor实现,通过PerpetualCache的HashMap存储数据,在query方法中优先检查缓存命中。缓存键CacheKey由SQL语句、参数等信息哈希生成。二级缓存则是跨会话的命名空间级缓存,通过Cache接口实现,支持多种缓存策略。两种缓存通过不同生命周期和范围共同优化系统性能,减少数据库访问。文章结合MyBatis 3.4.6源码,详细解读了缓存的实现细节和使用场景。

qq_45464560的博客 861

【Unity实战篇】 接入百度翻译,实现文本自动翻译功能

日常在做项目的过程中,游戏本地化几乎已经成为必不可少的一步。 本篇文章将演示怎样在Unity中接入百度翻译,实现文本自动翻译的功能。

努力前行,总会成为自己心中的那道光 9059

得物(毒)App潮鞋价格波动监控系统实战:从爬虫开发到数据可视化完整指南

本文将带领您从零开始构建一套完整的得物潮鞋价格监控系统,涵盖爬虫开发、数据存储、价格波动分析和可视化展示等全流程技术。我们将使用最新的Python技术栈,包括异步爬虫框架、智能代理池、反爬虫绕过技巧,以及基于机器学习的时间序列预测模型。无论您是想要追踪特定鞋款价格的潮流爱好者,还是希望构建商业级监控系统的开发者,这篇文章都将为您提供切实可行的解决方案。

2201_76125261的博客 2506

MyBatis缓存机制深度解析

本文系统分析了MyBatis的两级缓存机制。一级缓存为SqlSession级别,默认开启,能有效减少单会话内的重复查询;二级缓存为Mapper级别,需手动配置,支持跨会话共享数据。文章详细对比了两者的作用域、开启方式、失效场景等核心差异,并提供了Redis整合方案解决分布式环境下的缓存一致性问题。通过实际案例演示了缓存生效与失效的各种场景,同时给出了常见问题排查方法和最佳实践建议。掌握MyBatis缓存机制能显著降低数据库压力,提升系统响应速度,是优化数据

2401_83675559的博客 1229

通用抓取算法AnyGrasp(Graspnet)——本地部署并测试自定义输入数据

背景:GraspNet在数据采集方面,首先将相机固定到机械臂末端,对同一个场景拍摄256个不同的角度,同时场景中的每个物体都会提前采集好3D模型,之后将其投射到仿真环境中,在仿真环境中,对抓取位姿进行打标签,如此完成数据的采集。在运行官方的测试示例时,使用的是路径下的输入数据,可以分析下。color.png(输入):rgb图像(输出):输出的生成抓取位姿的图像depth.png(输入):和当前rgb图像对应的深度图像(保存格式是单通道uint16)meta.mat。

boss-dog 1329

MyBatis3源码深度解析(十七)MyBatis缓存(一)一级缓存和二级缓存的实现原理

缓存是MyBatis中非常重要的特性。合理使用缓存,可以减少数据库IO,显著提升系统性能;但在分布式环境下,如果使用不当则会带来数据一致性问题。在上一节【MyBatis3源码深度解析(十六)SqlSession的创建与执行(三)Mapper方法的调用过程】中提到,MyBatis提供了一级缓存和二级缓存来提升查询效率,一级缓存在BaseExecutor类中完成,二级缓存在CachingExecutor类中完成。

挑灯日记 记录自己 1605

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

MyBatis 缓存机制深度解析

Override// 自定义存储逻辑// 实现其他接口方法...-- 使用自定义缓存 --> < cache type = " com.example.CustomRedisCache " />-- 使用自定义缓存 --> < cache type = " com.example.CustomRedisCache " />-- 使用自定义缓存 --> < cache type = " com.example.CustomRedisCache " />

yuren_xia的博客 1114

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

MyBatis 执行流程详解:一级缓存与二级缓存深度解析

MyBatis 是一个优秀的持久层框架,它不仅简化了数据库操作,还提供了强大的缓存机制来提升查询性能。本文将深入探讨 MyBatis 的执行流程,并重点分析一级缓存和二级缓存的实现原理及其使用场景。

2401_84910501的博客 831

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

MyBatis 一二级缓存深度解析:原理、应用与脏读问题

级缓存基于 SqlSession 的生命周期,默认开启但存在跨会话脏读风险;二级缓存虽能实现跨会话数据共享,却需谨慎处理连表查询、集群部署等场景下的缓存同步难题。

小红的布丁的博客 1542

关于MyBatis的一级缓存和二级缓存的深度解析

在本篇文章中,将结合示例与源码,对MyBatis中的一级缓存和二级缓存进行说明。MyBatis3.5.6关于MyBatis的一级缓存,总结如下。MyBatis的一级缓存默认开启,且默认作用范围为SESSION,即一级缓存在一个会话中生效,也可以通过配置将作用范围设置为STATEMENT,让一级缓存仅针对当前执行的SQL语句生效;在同一个会话中,执行增删改操作会使本会话中的一级缓存失效;不同会话持有不同的一级缓存,本会话内的操作不会影响其它会话内的一级缓存。关于MyBatis的二级缓存,总结如下。

Java技术攻略的博客 1037

MyBatis 缓存机制深度解析:从底层源码到实战应用

在 MyBatis 框架的性能优化体系中,缓存机制是当之无愧的核心组件 —— 它通过减少数据库交互次数,极大降低了 IO 开销,是提升查询效率的关键手段。本文将从源码视角逐层拆解 MyBatis 的两级缓存架构,不仅剖析SqlSession级别的一级缓存、Mapper级别的二级缓存的底层实现,还会详解缓存 Key 的生成逻辑、装饰器模式的应用,最终帮你建立完整的缓存知识体系,避开实际开发中的常见误区。维度一级缓存(Local Cache)二级缓存(Global Cache)作用级别。

ljysee的博客 1319

【MyBatis二级缓存深度解析:缓存清理时机与最佳实践】

MyBatis二级缓存的清理机制是一个在简单性与灵活性之间权衡的典范。增删改操作执行后:这是最核心的清理触发点,保证数据一致性手动调用清理方法:提供灵活的手动控制能力定时刷新机制:防止脏数据长时间存留缓存淘汰策略:基于容量和访问模式的智能清理在实际应用中,需要根据业务特点选择合适的缓存策略和清理机制。对于读多写少、数据一致性要求不高的场景,可以积极使用二级缓存提升性能;对于写操作频繁或数据一致性要求高的场景,需要谨慎使用甚至禁用二级缓存。最终建议默认选择LRU策略。

m0_64006292的博客 907

MyBatis缓存机制深度解析:一级缓存、二级缓存与第三方缓存集成

MyBatis缓存主要分为两类:一级缓存(SqlSession级别的缓存)和二级缓存(Mapper级别的缓存)。此外,MyBatis还支持集成第三方缓存框架,以提供更灵活和强大的缓存解决方案。MyBatis的缓存机制是提高数据库查询性能的重要手段之一。通过合理使用一级缓存、二级缓存以及集成第三方缓存框架,可以显著减少数据库访问次数,提高应用性能。然而,在使用缓存时也需要注意数据一致性和缓存污染等问题,以确保应用的稳定性和可靠性。

hs_1024的博客 930

MyBatis一级缓存深度解析与最佳实践

(语句+参数),MyBatis 仅执行一次数据库操作,后续直接从内存返回结果。:减少重复查询,提升性能(尤其适用于循环操作同一数据的场景)。时,Spring 会将多个操作绑定到同一。:通过日志观察 SQL 执行次数。:SQL语句、参数值、分页参数(,一级缓存持续生效至事务结束。级别的缓存(默认开启)。

m0_75107803的博客 772

MyBatis 缓存深度解析(一级 / 二级缓存原理 + 实战 + 避坑)

缓存是将频繁访问的数据临时存储在内存中的机制减少数据库磁盘 IO 次数,降低数据库压力;内存读写速度远高于磁盘,提升查询响应效率(毫秒级→微秒级)。一级缓存是SqlSession 对象级别的本地缓存SqlSession 内部维护一个Map集合(Key:缓存标识;Value:查询结果),存储当前会话的查询数据;一级缓存生命周期与 SqlSession 完全绑定:SqlSession 创建则缓存生效,关闭 / 清空则缓存失效;缓存数据以对象引用形式存储(非序列化),读取性能极高。二级缓存是。

2302_79797878的博客 1220

MyBatis 缓存机制:一级缓存与二级缓存

MyBatis 缓存机制深度解析,MyBatis 采用两级缓存机制提升数据库查询性能:一级缓存(SqlSession 级别)是默认开启,线程私有,基于 HashMap 实现,随会话创建/关闭、执行更新操作或调用 clearCache() 时失效;二级缓存(Mapper 级别)需手动配置开启、可跨会话共享,要求 POJO 实现序列化,事务提交后生效,存在脏读风险。核心区别在于作用范围,共享性,性能。一级缓存适合事务内重复查询,二级缓存适合读多写少场景;注意跨 Mapper 操作时的数据一致性问题。

无论云泥意贯一 452

MyBatis缓存机制深度解析:一级缓存vs二级缓存,谁才是性能王者?

一级缓存:默认开启,不用白不用,但要注意增删改会清空缓存;二级缓存:适合读多写少的场景(比如用户信息查询、商品信息查询),如果是写多读少的场景,不建议用二级缓存,因为频繁的增删改会清空缓存,反而影响性能;数据一致性:使用二级缓存时,要注意可能出现的脏读问题,建议设置合理的刷新间隔(flushInterval);第三方缓存:MyBatis的二级缓存支持集成第三方缓存(比如Redis、Ehcache),如果需要更强大的缓存功能,可以考虑集成!缓存是把双刃剑,用得好性能翻倍,用不好反而会踩坑!

smile_WangDuoduo的博客 640

​MyBatis 二级缓存清理策略:深度解析与最佳实践​

在现代应用开发中,数据库访问往往是主要的性能瓶颈之一。为了缓解这一问题,缓存技术应运而生,它通过将频繁访问的数据存储在更快的介质(如内存)中,来减少对数据库的直接访问,从而显著提升系统吞吐量。MyBatis,作为 Java 生态中流行的持久层框架,提供了一级缓存和二级缓存这两级缓存机制。

一起探索IT的世界 778
上一篇: 【高性能系统设计必修课】:为什么顶尖工程师都在用分离栈规避内存碎片?
下一篇: ThreadLocal 的共享策略深度剖析(高级开发必知的5大误区)
CodePulse
博客等级 码龄2年 187粉丝 2233原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值