当前位置: 首页 > news >正文

自己实现的一个缓存数据库(搞着玩) .net Core/6/8/9

自己实现的一个缓存数据库(搞着玩)

    • 想法来源
    • 特点说明
  • 上代码
    • 主体
    • 基类
    • 测试类
  • `注`

想法来源

做过一个小型项目,客户要求易移植,不能使用收费的数据库,最好是一个包搞定,尝试过用sqlite,在部分linux上可能需要自己安装环境,比较麻烦
mysql也需要安装,客户技术实力比较弱,不安装多的依赖,一键运行最好

特点说明

支持多线程
支持多表
适合小型项目,不用安装配置其它数据库,可以做到只有一个包,一键启动
如果将主键id调整为手动指定的字符串,可以作为系统的配置库来使用,数据都在内存里面,读取速度快
由于是数据是全量进行持久化保存,所以不支持太大的数据量

上代码

主体


namespace Memory.Db
{/// <summary>/// 内存数据库/// 支持多线程/// 支持多表/// 不支持大量数据/// 建议每个表数据量不要超过1w,或者数据文件大小保持在5M以内/// 数据都在内存里面,所以读取速度会相当快/// 适合项目///     1.小型项目///     2.数据量小 不想使用数据库,安装配置麻烦/// </summary>public class CacheDB:ISingleton{/// <summary>/// 雪花id类/// </summary>readonly SnowflakeId _sid;public CacheDB(SnowflakeId sid){_sid = sid;}//数据库private static ConcurrentDictionary<string, ConcurrentDictionary<long, dynamic>> _db = new();//数据存放路径private string _fielpath = "wwwroot/cachedb/";//锁对象private object lockobj = new object();/// <summary>/// 新增或修改/// </summary>/// <typeparam name="T"></typeparam>/// <param name="item"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public T AddOrUpdate<T>(T item) where T : CacheDBEntityBase, new(){//取得表var table = GetTable<T>();//判断是否新增if (item.Id == 0){//新增item.Id = _sid.GenerateId();item.CreatedTime = DateTime.Now;}else{//修改if (!table.ContainsKey(item.Id)) throw new Exception("数据不存在");var old = table[item.Id];item.CreatedTime = old.CreatedTime;//将原来的创建时间值取过来,防止被空值覆盖item.UpdateTime = DateTime.Now;}///新增或修改table.AddOrUpdate(item.Id, item, (a, b) => item);//保存快照SaveToFile<T>();return item;}/// <summary>/// 删除/// </summary>/// <typeparam name="T"></typeparam>/// <param name="item"></param>/// <exception cref="Exception"></exception>public void Delete<T>(T item) where T : CacheDBEntityBase, new(){//取得表var table = GetTable<T>();//按id删除if (item.Id == 0) throw new Exception("未提供Id");if (table.ContainsKey(item.Id)){table.Remove(item.Id, out _);//保存快照SaveToFile<T>();}}/// <summary>/// 返回列表/// </summary>/// <typeparam name="T"></typeparam>/// <returns></returns>public List<T> GetList<T>() where T : CacheDBEntityBase, new(){var table = GetTable<T>();//这里先序列化成json,再序列化为指定类型,不然会出现值为空的情况var json = table.ToJson();var data = json.ToEntity<Dictionary<long, T>>();return data.Select(x => x.Value).ToList();}/// <summary>/// 按id查询单条/// </summary>/// <typeparam name="T"></typeparam>/// <param name="id"></param>/// <returns></returns>public T Find<T>(long id) where T : CacheDBEntityBase, new(){var table = GetTable<T>();var mod= table[id] as T;return mod;}/// <summary>/// 取得表/// </summary>/// <typeparam name="T"></typeparam>/// <returns></returns>public ConcurrentDictionary<long, dynamic> GetTable<T>() where T: CacheDBEntityBase,new(){//获取表名var _table = typeof(T).Name;ConcurrentDictionary<long, dynamic> data;//判断表是否已经存在于缓存if (!_db.ContainsKey(_table)){//保存路径var _path = $"{_fielpath}{_table}.json";if (File.Exists(_path)){//如果文件存在,从文件读取数据到缓存var json = File.ReadAllText(_path);_db[_table] = json.ToEntity<ConcurrentDictionary<long, dynamic>>();}else{//如果文件不存在,创建新的表_db[_table] = new ConcurrentDictionary<long, dynamic>();}}data = _db[_table];//返回表return data;}/// <summary>/// 快照/// </summary>/// <typeparam name="T"></typeparam>/// <returns></returns>private async Task SaveToFile<T>(){lock (lockobj){var _table = typeof(T).Name;var json = _db[_table].ToJson();var _path = $"{_fielpath}{_table}.json";Directory.CreateDirectory(_fielpath);File.WriteAllText(_path, json);}}}
}

基类

public class CacheDBEntityBase{/// <summary>/// 主键/// </summary>public long Id { get; set; }/// <summary>/// 创建时间/// </summary>public DateTime CreatedTime { get; set; }/// <summary>/// 修改时间/// </summary>public DateTime? UpdateTime { get; set; }}

测试类

    public class aa: CacheDBEntityBase{public string name { get; set; }public string name2 { get; set; }public string name3 { get; set; }public string name4 { get; set; }public string name5{ get; set; }}public class bb : CacheDBEntityBase{public string name { get; set; }}

上面代码中的部分内容说明
ToJson 方法将实体转为json字符串
ToEntity 方法将json字符串转为指定的类型
SnowflakeId 雪花id类 用来生成id
上面代码中没有这些内容的实现,请自行实现替代

http://www.lryc.cn/news/532622.html

相关文章:

  • 在Qt中,slots 关键字有什么用?
  • 如何查看linux机器有几个cpu
  • Swoole如何处理内存泄漏
  • Llama最新开源大模型Llama3.1
  • Pixflow - CL-DJI Drone LUTs 120个大疆Drone无人机相机航拍电影级镜头LUT调色预设
  • 了解AI绘图,Stable Diffusion的使用
  • idea整合deepseek实现AI辅助编程
  • llama_index
  • Spring Boot统一异常拦截实践指南
  • Games104——游戏引擎Gameplay玩法系统:基础AI
  • stm32生成hex文件详解
  • 【Windows 开发NVIDIA相关组件】CUDA、cuDNN、TensorRT
  • AI大模型(二)基于Deepseek搭建本地可视化交互UI
  • 各种协议设计
  • DockerFile详细学习
  • Windows Docker笔记-简介摘录
  • TeamSpeak开黑频道加入 —— 点歌机器人 (细致讲解100%学会)
  • 2025简约的打赏系统PHP网站源码
  • 网络安全 | 零信任架构:重构安全防线的未来趋势
  • JavaScript系列(62)--实时通信系统实现详解
  • 【蓝桥杯嵌入式】2_LED
  • 代码随想录day06
  • Spring @PropertySource:让你的应用配置更加模块化和可维护
  • 【Java】MyBatis动态SQL
  • 旅行社项目展示微信小程序功能模块和开发流程
  • litemall,又一个小商场系统
  • WGCLOUD监控系统部署教程
  • Python大数据可视化:基于Python的王者荣耀战队的数据分析系统设计与实现_flask+hadoop+spider
  • (苍穹外卖)项目结构
  • ASP.NET Core筛选器Filter