尧图精选

Sa-Token SaTokenDao 数据持久接口完全指南:会话数据如何写入与读取

🕒 发布时间:2026/9/13 15:46:39 📁 来源:尧图网络
Sa-Token SaTokenDao 数据持久接口完全指南会话数据如何写入与读取【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token导读SaTokenDao是 Sa-Token 框架的数据持久层接口负责所有会话数据登录 Token、Session、临时令牌、API 数据等的底层写入与读取是整个框架与存储介质之间的唯一抽象边界。本文基于当前仓库 sa-token-doc/api/sa-token-dao.md 展开深入讲解该接口的常量约定、字符串/对象/Session 三大读写体系、会话搜索能力并结合源码揭示其默认内存实现、自动跟随机制与过期清理原理。读完本文你将掌握 SaTokenDao 的全部 API 语义、默认行为边界以及如何通过自定义实现把会话数据迁移到 Redis、MongoDB 等任意存储介质。一、SaTokenDao 在框架中的定位Sa-Token 的所有会话数据——包括登录后产生的 Token、SaSession 会话对象、Same-Token 临时令牌、API Key 授权信息等——都不是直接堆在业务代码里的而是统一通过一个名为SaTokenDao的接口完成存取。从源码结构看该接口位于 sa-token-core/src/main/java/cn/dev33/satoken/dao/SaTokenDao.java接口注释明确说明此接口的不同实现类可将数据存储至不同位置如内存 Map、Redis 等等。如果你要自定义数据存储策略也需通过实现此接口来完成。也就是说SaTokenDao 就是 Sa-Token 的存储抽象层框架核心逻辑只依赖这一份接口定义而数据到底放在 JVM 内存里、还是放在 Redis 中间件里完全由接口的实现类决定。在运行期框架通过 SaManager 统一持有当前生效的 SaTokenDao 实例SaManager.setSaTokenDao(dao)手动装载自定义实现替换旧实例时会调用旧实例的destroy()测试用例见 SaManagerTestSaManager.getSaTokenDao()获取当前生效实例若尚未装载则自动懒加载默认实现SaTokenDaoDefaultImpl。框架内部的各类模板类如SaSession、SaSameTemplate、SaApplication全部通过SaManager.getSaTokenDao()发起底层读写因此开发者只需替换这一个 Bean即可实现全框架存储层的迁移。二、核心常量永不过期与不存在SaTokenDao接口定义了两个全局常量用于表达两种特殊状态定义见 SaTokenDao.java/** 常量表示一个 key 永不过期在一个 key 被标注为永远不过期时返回此值 */ long NEVER_EXPIRE -1; /** 常量表示系统中不存在这个缓存在对不存在的 key 获取剩余存活时间时返回此值 */ long NOT_VALUE_EXPIRE -2;常量值语义典型出现场景SaTokenDao.NEVER_EXPIRE-1key 永不过期写入数据时以-1作为 timeout 表示永久存储读取存活时间时若该 key 被标注为永不过期则返回此值SaTokenDao.NOT_VALUE_EXPIRE-2系统中不存在该缓存对不存在的 key或已过期的 key获取剩余存活时间时返回此值这两个常量在写入与读取两个方向都有明确约定写入方向set/setObject/setSession的timeout参数遵循值大于 0 时限时存储值等于 -1 时永久存储值等于 0 或小于等于 -2 时不存储的规则接口注释见 SaTokenDao.java。读取方向getTimeout/getObjectTimeout/getSessionTimeout返回剩余秒数永不过期的 key 返回NEVER_EXPIRE不存在的 key 返回NOT_VALUE_EXPIRE。上述语义在默认实现的定时缓存 SaTimedCacheTest 中有完整断言覆盖例如以NOT_VALUE_EXPIRE写入不会真正存储数据、以NEVER_EXPIRE写入后读取存活时间恒为-1等。三、字符串读写 APISaTokenDao针对字符串数据提供了 6 个基础方法见 SaTokenDao.javadao.get(key); // 获取 Value如无返空 dao.set(key, value, timeout); // 写入 Value并设定存活时间单位秒 dao.update(key, value); // 更新 Value过期时间不变 dao.delete(key); // 删除 Value dao.getTimeout(key); // 获取 Value 的剩余存活时间单位秒 dao.updateTimeout(key, timeout); // 修改 Value 的剩余存活时间单位秒每个方法的核心语义get(key)按 key 取值不存在时返回null。注意与过期但未清理的区别——所有实现都应保证已过期的 key 视为不存在。set(key, value, timeout)写入并设置存活时间。timeout单位是秒遵循上节提到的常量约定-1永久、0或 -2不存储、正数限时。update(key, value)仅替换值不重置过期时间。这是与set的关键差异适合会话续期外的纯数据更新场景例如更新用户信息但保持原 Token 的到期时间不变。delete(key)删除该 key 及其过期记录。getTimeout(key)获取剩余存活秒数遵循NEVER_EXPIRE/NOT_VALUE_EXPIRE返回约定。updateTimeout(key, timeout)仅修改剩余存活时间而不动数据本身常用于续期操作。字符串读写的底层实现差异字符串读写的方法定义统一在接口上但不同实现类可以自由选择原生存储字符串还是把字符串当对象存储内存型实现默认实现类继承SaTokenDaoByStringFollowObject字符串读写自动跟随对象读写见 SaTokenDaoByStringFollowObject.java例如get(key)直接转为(String) getObject(key)。中间件型实现如 Redis 插件实现类继承SaTokenDaoByObjectFollowObject对象读写自动跟随字符串读写即先由序列化器把对象转成 JSON 字符串再存储见 SaTokenDaoByObjectFollowObject.java。四、对象读写 API对象读写是字符串读写的泛型版本负责把任意 Java 对象序列化后存储见 SaTokenDao.javadao.getObject(key); // 获取 Object如无返空 dao.getObject(key, classType); // 获取 Object并指定转换类型 dao.setObject(key, value, timeout); // 写入 Object并设定存活时间单位秒 dao.updateObject(key, value); // 更新 Object过期时间不变 dao.deleteObject(key); // 删除 Object dao.getObjectTimeout(key); // 获取 Object 的剩余存活时间单位秒 dao.updateObjectTimeout(key, timeout); // 修改 Object 的剩余存活时间单位秒三个值得注意的细节带类型的读取getObject(key, classType)在需要反序列化为具体类型时使用。例如SaTokenDaoBySessionFollowObject读取 Session 时正是通过getObject(sessionId, SaStrategy.instance.sessionClassType)将 JSON 反序列化为指定 Session 类型见 SaTokenDaoBySessionFollowObject.java。序列化由谁负责在对象跟随字符串的实现路线中序列化与反序列化统一交给SaManager.getSaSerializerTemplate()完成见 SaTokenDaoByObjectFollowString.java因此更换 JSON 序列化插件如 sa-token-jackson、sa-token-fastjson2 等即会改变对象落库的格式。默认实现的类型擦除默认内存实现中getObject(key, classType)直接强转返回见 SaTokenDaoDefaultImpl.java因为内存里存的就是原始对象引用无需真正反序列化。五、SaSession 读写 APISaSessionSa-Token 的会话对象读写本质上是对象读写的特化封装接口上同样提供了 6 个方法见 SaTokenDao.javadao.getSession(sessionId); // 获取 Session如无返空 dao.setSession(session, timeout); // 写入 Session并设定存活时间单位秒 dao.updateSession(session); // 更新 Session过期时间不变 dao.deleteSession(sessionId); // 删除 Session dao.getSessionTimeout(sessionId); // 获取 Session 的剩余存活时间单位秒 dao.updateSessionTimeout(sessionId, timeout); // 修改 Session 的剩余存活时间单位秒默认行为Session 读写自动跟随对象读写。次级接口 SaTokenDaoBySessionFollowObject 提供了全套 default 实现getSession(sessionId)→getObject(sessionId, sessionClassType)setSession(session, timeout)→setObject(session.getId(), session, timeout)updateSession(session)→updateObject(session.getId(), session)其余方法依次映射到对应的 Object 方法也就是说Session 的存储 key 就是其自身的id开发者实现自定义存储时无需为 Session 单独开发一套读写逻辑只要对象读写可用Session 读写即可自动工作。框架内SaSession、SaSessionCustomUtil等类正是通过这些方法实现会话的更新、删除与超时查询例如 SaSession.java 中的update()、delete()等操作。六、会话管理数据搜索除常规读写外SaTokenDao还提供一个搜索方法用于按前缀与关键字遍历已存储的数据见 SaTokenDao.javadao.searchData(prefix, keyword, start, size, sortType);参数说明参数类型含义prefixString前缀只搜索 key 以该前缀开头的条目keywordString关键字进一步过滤 key 中包含该关键字的条目startint开始处索引分页起点sizeint获取数量-1代表从start处一直取到末尾sortTypeboolean排序类型true正序false反序返回值为查询到的 key 集合ListString。这一能力是框架实现会话管理 / 在线用户列表 / 按前缀检索等运维功能的基础例如 SaApplication 在搜索应用数据时即调用searchData(prefix, , 0, -1, true)拉取全部匹配项。默认实现中searchData基于SaTimedCache的keySet()交由SaFoxUtil.searchList完成过滤与排序见 SaTokenDaoDefaultImpl.java。注意内存实现可以做到全量遍历但 Redis 等中间件实现通常会基于 KEYS / SCAN 类指令实现大数据量下性能表现取决于底层存储方案这属于选择实现时的权衡点。七、默认实现基于 SaTimedCache 的内存缓存框架自带的默认实现是SaTokenDaoDefaultImpl其完整说明为基于 SaTimedCache - ConcurrentHashMap内存缓存系统重启后数据丢失见 SaTokenDaoDefaultImpl.java。它的几个关键特征存储结构内部持有SaTimedCache由两个SaMapPackageForConcurrentHashMap本质为 ConcurrentHashMap 包装分别存放数据和过期时间单位毫秒存的是到期时间戳而非剩余秒数见 SaTimedCache.java。过期策略惰性检查 异步循环扫描见 SaTimedCache.java惰性检查每次getObject/getObjectTimeout时先调用clearKeyByTimeout(key)若发现该 key 已到期则立即清除SaTimedCache.java异步扫描init()被调用时启动一个后台线程周期性调用refreshDataMap()清理全部过期 keySaTimedCache.java。清理周期可配置后台清理线程的休眠间隔由配置项dataRefreshPeriod控制默认 30 秒设置为-1可关闭定时清理仅保留惰性检查见 SaTokenConfig.java。生命周期钩子实现类通过init()/destroy()两个 default 方法感知装载与卸载——默认实现分别在init()中启动清理线程、在destroy()中结束清理线程见 SaTokenDaoDefaultImpl.java。需要特别强调的是默认实现的数据仅存在于 JVM 内存中进程重启即全部丢失。因此单机演示、快速体验阶段可以直接使用而生产环境多实例部署时必须替换为 Redis 等分布式存储实现。八、自定义实现接入 Redis 等存储介质既然SaTokenDao是唯一的存储抽象层自定义存储策略只需两步1. 实现SaTokenDao接口或继承次级接口简化工作若你的存储方案是中间件型如 Redis、MongoDB天然以字符串/字节存储推荐继承 SaTokenDaoByObjectFollowObject此时你只需要实现 6 个字符串读写方法get/set/update/delete/getTimeout/updateTimeout对象与 Session 读写会自动通过序列化器转化为字符串读写若你的存储方案是内存型如 Caffeine 等本地缓存天然以对象引用存储推荐继承 SaTokenDaoByStringFollowObject只需要实现对象读写方法即可。仓库中的 Redis 插件如sa-token-plugin/sa-token-redis-template、sa-token-plugin/sa-token-redisson、sa-token-plugin/sa-token-alone-redis等正是这一抽象下的具体落地可作为自定义实现的参考样板。2. 装载实现类通过SaManager.setSaTokenDao(dao)手动装载或在 Spring 等容器环境中注册为 Bean 由框架自动注入。装载时若已有旧实例框架会先调用旧实例的destroy()再切换测试见 SaManagerTest替换为null后再次调用getSaTokenDao()会重新懒加载默认实现SaManagerTest。九、小结SaTokenDao是 Sa-Token 数据持久层的唯一抽象接口其设计要点可归纳为三套读写体系字符串get/set/update/delete/getTimeout/updateTimeout、对象同名 Object 变体、Session同名 Session 变体方法语义一一对应两个状态常量NEVER_EXPIRE -1表示永不过期NOT_VALUE_EXPIRE -2表示缓存不存在一套搜索能力searchData(prefix, keyword, start, size, sortType)支持按前缀、关键字分页检索已存 key自动跟随机制Session 读写自动跟随对象读写而对象读写既可跟随字符串读写中间件型也可反向由字符串跟随对象内存型开发者可按存储介质特性只实现最小方法集默认内存实现基于SaTimedCacheConcurrentHashMap采用惰性检查 异步循环扫描双通道过期清理重启即失适合单机演示生产环境应通过自定义实现接入 Redis 等分布式存储实现会话数据跨实例共享。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →