Dapper缓存是分层轻量内存缓存,不存结果数据而缓存执行与映射逻辑:一级缓存用SQL哈希+参数类型+连接标识+结果类型键查ConcurrentDictionary复用执行逻辑;二级缓存按Type和DeserializerKey双重索引生成差异化反序列化函数;键由GetColumnHash加权列名与类型哈希生成;默认无主动过期,仅被动淘汰低效项并提供手动清理与监控接口。

Dapper的缓存机制不是单一的“结果缓存”,而是分层、轻量、内存驻留的多级缓存体系,核心目标是消除重复解析和映射开销,而非替代Redis这类分布式缓存。它不缓存查询结果数据本身(比如100条User记录),而是缓存“怎么执行”和“怎么转换”的逻辑。
每次执行SQL时,Dapper会生成一个唯一的 Identity 键,包含:SQL语句哈希值、参数类型、连接字符串标识、结果类型。这个键用于查 ConcurrentDictionary<identity cacheinfo></identity> —— 全局静态线程安全字典。
命中后直接复用已编译的执行逻辑,包括:
ParamReader)DeserializerState)避免了每次查询都重新编译命令、反射获取属性、遍历DataReader列等操作。
这部分由 TypeDeserializerCache 管理,采用双重键控设计:
Type(如 Product)索引,用静态 Hashtable byType 存储DeserializerKey(含列名数组、列类型、起始偏移、是否允许null等)区分不同查询上下文例如:SELECT Id, Name FROM Products 和 SELECT Name, Price FROM Products 即使映射到同一类型,也会生成两个不同的反序列化函数,互不干扰。
关键方法是 GetColumnHash,它对DataReader的列信息做加权哈希:
GetName(i) 和 GetFieldType(i) 的哈希值参与运算startBound 和 length 支持跳过前几列或只取部分列(适配匿名对象、多结果集)这种设计让缓存键真正反映“数据结构特征”,而不是简单拼接SQL字符串。
Dapper默认不主动过期缓存,但有被动淘汰策略:
SqlMapper.PurgeQueryCacheByType(typeof(T)) 或 SqlMapper.PurgeQueryCache()
SqlMapper.GetCachedSQLCount()、SqlMapper.GetCachedSQL(ignoreHitCountAbove: 5) 查低频查询注意:CommandFlags.NoCache 可临时绕过整个缓存链,适合动态SQL或实时性极高的场景。
基本上就这些。它不复杂,但容易忽略——缓存生效的前提是SQL文本、参数类型、目标类型、连接字符串(或至少Provider)保持稳定。只要其中一项变了,就是新缓存键。
以上就是Dapper的缓存机制是什么 Dapper内部缓存原理解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号