thinkphp 5 模型查询默认不走缓存,需显式调用 cache() 方法并置于查询链中间;with() 关联查询不能直接缓存,须拆分主表与关联表分别缓存;推荐自定义含业务标识的缓存 key,并在增删改后手动清理对应缓存。

ThinkPHP 5 的模型查询默认完全不走缓存,哪怕你已配置好 Redis 或 File 驱动,select()、find() 这些方法也不会自动读写缓存。必须显式调用 cache() 方法,且要放在查询链的中间位置。
基础写法:cache() 必须插在查询过程中
正确示例:
UserModel::where('status', 1)->cache(3600)->select()UserModel::where('id', 123)->cache('user_123', 7200)->find()
错误写法(无效):
-
UserModel::where('status', 1)->select()->cache(3600)——select()已返回数组,无法链式调用 -
cache('key', $data)直接传值 —— 这是通用缓存写入,不是模型查询缓存
关联查询 with() 不能直接挂 cache()
with() 加载关联时,cache() 会失效或返回空关联数据,因为 TP5 的缓存键只基于主表 SQL,不包含关联子查询逻辑。
- ❌ 错误:
UserModel::with('profile')->cache(600)->select() - ✅ 正确:拆开缓存
– 主表缓存:$users = UserModel::where('status', 1)->cache('user_active_list', 3600)->select()
– 关联单独查并缓存:$ids = array_column($users, 'id'); ProfileModel::where('user_id', 'in', $ids)->cache('profile_by_user_ids', 3600)->select()
自定义缓存 key 更安全可靠
默认 key 是 SQL 的 MD5 值,极易因空格、换行、数据库前缀、环境差异而变化,导致缓存不命中或错乱。
- 推荐写法:
UserModel::where('status', 1)->cache('user_active_v202610', 3600)->select() - key 建议含业务含义 + 版本/时间标识,避免跨模块冲突(如加前缀
api_user_、admin_user_) - File 缓存驱动下,key 总长度建议 ≤255 字符,否则 Windows 下可能静默失败
增删改后必须手动清理对应缓存
模型的 save()、delete()、update() 不会自动清除相关缓存,需开发者主动处理,否则用户看到的是旧数据。
- 新增/修改用户后:
Cache::delete('user_active_v202610') - 删除用户后:
Cache::delete('user_123') - 若用了缓存标签(如
Cache::tag('user')->set(...)),可用Cache::clear('user')批量清除
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











