golang实现自定义驱动的Cache

近期在写 ActivedRouter项目的时候需求一个缓存模型,要求缓存模型支持不同驱动,例如:memory、file、redis、mysql,实现思路代码如下:


cache.go文件,定义缓存对外接口

//ActivedRouter
//Author:usher.yue
//Amail:usher.yue@gmail.com
//TencentQQ:4223665
//缓存驱动接口定义
//可以自定义扩展驱动类型 默认是 memory driverpackage cacheimport ("./driver"
)//cache接口声明
type Cacher interface {GetStorage() driver.ContainererSet(k string, v interface{})Get(k string) (interface{}, bool)Del(k string)Has(k string) bool
}//create memory cache
//type "file" or "memory"
func Newcache(cacheType string) Cacher {switch cacheType {case "memory":return &driver.CacheImpl{Driver: driver.NewMapContainer()}case "file":{return &driver.CacheImpl{Driver: driver.NewFileContainer()}}case "mysql":{return &driver.CacheImpl{Driver: driver.NewMysqlContainer()}}case "redis":{return &driver.CacheImpl{Driver: driver.NewRedisContainer()}}case "mongodb":{return &driver.CacheImpl{Driver: driver.NewMongoContainer()}}}return nil
}


driver.go  实现驱动,这里我只利用Map实现了,具体其他驱动可自行实现

//ActivedRouter
//Author:usher.yue
//Amail:usher.yue@gmail.com
//TencentQQ:4223665
//缓存驱动接口定义
//可以自定义扩展驱动类型 默认是 memory cachepackage driver//容器接口声明
type Containerer interface {PushKVPair(k, v interface{}) ContainererEraseKVPair(k interface{}) ContainererPushKVMaps(maps ...map[string]interface{}) ContainererResetKVPair(k string, v interface{}) ContainererResetOrAddKVPair(k string, v interface{}) ContainererResetKVPairs(kvMaps map[string]interface{}) ContainererResetOrAddKVPairs(kvMaps map[string]interface{}) ContainererExist(k interface{}) boolGetData() *map[string]interface{}
}//基于内存实现的缓存
type CacheImpl struct {Driver Containerer //数据缓存驱动
}func (self *CacheImpl) Exist(k interface{}) bool {return self.Driver.Exist(k)
}func (self *CacheImpl) GetStorage() Containerer {return self.Driver
}//set
func (self *CacheImpl) Set(k string, v interface{}) {self.Driver.PushKVPair(k, v)
}//get
func (self *CacheImpl) Get(k string) (interface{}, bool) {mapData := *self.Driver.GetData()val, ok := mapData[k]return val, ok
}//erase
func (self *CacheImpl) Del(k string) {self.Driver.EraseKVPair(k)
}//has
func (self *CacheImpl) Has(k string) bool {mapData := *self.Driver.GetData()_, ok := mapData[k]return ok
}//Map实现的内存驱动
type MapContainer struct {data map[string]interface{}
}//创建数据channer
func NewMapContainer() *MapContainer {return &MapContainer{data: make(map[string]interface{})}
}func (this *MapContainer) PushKVPair(k, v interface{}) Containerer {if key, ok := k.(string); !ok {panic("key必须是string类型!")} else {this.data[key] = v}return this
}func (this *MapContainer) Exist(k interface{}) bool {return true
}func (this *MapContainer) EraseKVPair(k interface{}) Containerer {if key, ok := k.(string); !ok {panic("key必须是string类型!")} else {delete(this.data, key)}return this
}
func (this *MapContainer) PushKVMaps(maps ...map[string]interface{}) Containerer {for _, itemMap := range maps {for itemKey, itemValue := range itemMap {this.PushKVPair(itemKey, itemValue)}}return this
}
func (this *MapContainer) ResetKVPair(k string, v interface{}) Containerer {if _, ok := this.data[k]; ok {this.data[k] = v}return this
}
func (this *MapContainer) ResetOrAddKVPair(k string, v interface{}) Containerer {this.data[k] = vreturn this
}func (this *MapContainer) ResetKVPairs(kvMaps map[string]interface{}) Containerer {for k, v := range kvMaps {if _, ok := this.data[k]; ok {this.data[k] = v}}return this
}func (this *MapContainer) ResetOrAddKVPairs(kvMaps map[string]interface{}) Containerer {for k, v := range kvMaps {this.data[k] = v}return this
}func (this *MapContainer) GetData() *map[string]interface{} {return &this.data
}













本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290447.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C和指针之函数之求最大公约数

1、求最大公约数 求公约数的规则如下/*** M % N 0 : N*gcd(M, N) * M % N R, R > 0 : gcd(N, R)*/ 2、代码实现 #include <stdio.h> /*** M % N 0 : N*gcd(M, N) * M % N R, R > 0 : gcd(N, R)*/int gcd(int …

关于c#调用c编译器

这个已经过了好久了具体的实现代码没得&#xff0c;但是大致思路自己整理了一下&#xff1a; 首先要调用c编译器&#xff0c;process.start&#xff08;&#xff09;&#xff1b; 之后需要自己来进行编译器对代码执行的命令。 转载于:https://www.cnblogs.com/why1115/p/481032…

【自定义控件】c#winform自定义控件实现标签控件

介绍首先我们设计这个控件的时候要明白控件是怎样交互的&#xff0c; 熟悉b站的小伙伴应该知道 &#xff0c;我们上传视频的时候会去选择标签 &#xff0c;我们输入标签文本 按下回车就代表该标签已经添加成功了&#xff0c;效果图如下&#xff01;控件拆分我们首先拆分一下该控…

ASP.NET 使用Ajax(转)

之前在Ajax初步理解中介绍了对Ajax的初步理解&#xff0c;本文将介绍在ASP.NET中如何方便使用Ajax&#xff0c;第一种当然是使用jQuery的ajax&#xff0c;功能强大而且操作简单方便&#xff0c;第二种是使用.NET封装好的ScriptManager。 $.ajax向普通页面发送get请求 这是最简单…

printk函数出现延迟输出的问题

错误描述 关于测试内核read接口 有如下代码片段&#xff1a; static ssize_t hello_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos){int ret 0;printk("[read task]count%ld", count);memcpy(readbuf, kerneldata, sizeof(kerneldata));…

个人博客(05)

昨天&#xff1a;设计并制作了添加图书信息的界面 今天&#xff1a;准备学习制作修改店铺的界面问题&#xff1a;页面消息的提醒转载于:https://www.cnblogs.com/yibao/p/6849805.html

C和指针之函数之把数字字符串转为整数并且返回这个数字(ascii_to_integer)

1、问题 *字符串必须包含一个或多个数字,函数应该把这些数字字符转换为整数并且 *返回这个值,如果脂肪层参数包含了任何非数字字符,函数就要返回0,不考 *虑溢出情况 2、代码实现 #include <stdio.h>/***字符串必须包含一个或多个数字,函数应该把这些数字字符转…

如何有效的在 LINQ 查询中处理异常?

咨询区 Jader Dias参考下面的代码&#xff1a;myEnumerable.Select(a > ThisMethodMayThrowExceptions(a));如何保证在 Linq 的查询过程中即使抛出了异常&#xff0c;查询不会被提前中断&#xff0c;就好像在每层迭代上都有默认的 try catch 块。回答区 LeBaptiste我写了一个…

rman备份,crontab计划任务没有生成备份文件

利用crontab 执行计划和RMAN结合来实现 数据库的自动备份现象&#xff1a;利用计划任务来执行备份&#xff0c;只是生成了目录&#xff0c;却没有生成备份文件1&#xff1a; 手动执行备份脚本&#xff0c;没有问题2&#xff1a;crontab 计划任务&#xff0c;能够生成目录&#…

C和指针之函数之求参数列表中的最大值

1、问题 *编写一个叫max_list函数&#xff0c;它用于检查任意数目的整形参数*并返回他们中的最大值&#xff0c;参数列表必须以一个负数结尾&#xff0c;提*示列表的结束2、代码实现 #include <stdio.h> #include <stdarg.h> /***编写一个叫max_list函数&#xff0…

fir.im 持续集成技术实践

互联网时代&#xff0c;人人都在追求产品的快速响应、快速迭代和快速验证。不论是创业团队还是大中型企业&#xff0c;都在探索属于自己的敏捷开发、持续交付之道。fir.im 团队也在全面实施敏捷&#xff0c;并推出新持续集成服务— flow.ci &#xff0c;以帮助企业将开发测试流…

Redis调用及使用

首先第一步&#xff1a; 添加引用1.ServiceStack.DLLServiceStack.Interfaces.DLLServiceStack.ServiceInterface.DLL以上引用都可以在网上下载到2.调用&#xff1a;demo&#xff1a; stringticket "" ;stringhost "localhost" ;stringelementKey "…

MYSQL-skip-networking

1、跳过tcp/ip协议通信&#xff1a;[mysqld]# The TCP/IP Port the MySQL Server will listen onport3306#log_outputTABLEskip-networking #添加这一行然后重启服务2、测试连接&#xff1a;C:\Documents and Settings\Administrator>mysql -u root -pEnter password:ERROR…

宇宙最強的IDE - Visual Studio 25岁生日快乐

每位开发者从入门开始或多或少都会接触过 Visual Studio &#xff0c; 现今的 Visual Studio 除了支持传统的 C , C# , Visual Basic.NET ,F# 的编程语言外&#xff0c;还可以做 Python , Node.js 的开发。在应用场景上也从单一的桌面应用&#xff0c;延伸到 Web &#xff0c; …

C和指针之实现可变参数函数编译出现expanded from macro ‘va_arg‘ #define va_arg(ap, type) 解决办法

1、问题 编译可变参数函数里面有va_arg函数的时候提示这个错误 expanded from macro va_arg #define va_arg(ap, type) 2、原因 我没有考虑“默认参数提升”问题 如果一个函数的形参类型未知, 例如使用了Old Style C风格的函数声明,或者函数的参数列表中有 ...,那么调…

有没有一段代码,让你觉得人类的智慧也可以璀璨无比?【转】

转自&#xff1a;https://www.zhihu.com/question/30262900 作者&#xff1a;烧茄子链接&#xff1a;https://www.zhihu.com/question/30262900/answer/48741026来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。当然是这个…

maven中pom.xml中的scope讲解

一、compile&#xff1a;编译范围compile是默认的范围&#xff1b;如果没有提供一个范围&#xff0c;编译范围依赖在所有的classpath 中可用&#xff0c;同时它们也会被打包。而且这些dependency会传递到依赖的项目中。 二、provided&#xff1a;已提供范围provided 明了depend…

C和指针之函数之实现简单的printf函数(支持%d, %f, %c, %s)

1、问题 *简化printf函数,能够处理%d, %f, %c, %s格式码,假设已经存在 *print_integer和print_float函数,另外2个类型用put char来打印 思路: void va_start(va_list ap, last);// 取第一个可变参数的指针给ap,// last是函数声明中的最后一个固定参数(比如printf函数原型…

python 面试宝典--集各家之所长,乱七八糟于一体

1. 在判断object是否是class的instances时&#xff0c;type和isinstance函数的区别&#xff1f; type(obj) > <type instance> type(cls) > <type classobj> 由上可知&#xff0c;所有obj type后统一为 instance type&#xff1b; 而cls type后统一为classob…

如何使用 abp 创建 module 并应用单独的数据库迁移

最近在学习使用 abp 来做一些小程序。abp 是一个功能丰富的 .NET 开发框架&#xff0c;完全开源&#xff0c;遵循 DDD&#xff08;领域驱动&#xff09;设计模式&#xff0c;支持微服务开发&#xff0c;集成了 Identity、角色权限、本地化、动态代理、后台任务、分布式消息、审…