简述:go-cache 是一个基于内存的、高速的,存储k-v格式的缓存工具。它适用于运行在单台机器上的应用程序,可以存储任何数据类型的值,并可以被多个goroutine安全地使用。
go-cache 不打算用作持久数据存储,但是可以将整个缓存数据保存到文件(或任何io.Reader/Writer)中,并且能快速从中指定数据源加载,快速恢复状态。 大家可以去看看go-cache的源码,提供了很多设置获取删除缓存的方法,比如:SetDefault() , Add(), Replace(), Increment(), IncrementFloat(), IncrementInt8(), IncrementFloat64()等方法
LoginController.go (后面会提取封装到项目公共拓展库里)
// go get "github.com/patrickmn/go-cache"
// go get一下go-cache库
package controller
import (
"encoding/json"
"fmt"
"github.com/go-playground/validator/v10"
"github.com/dgrijalva/jwt-go"
"project/utils/response"
"time"
//"time"
//"project/models"
"project/requests"
"github.com/gin-gonic/gin"
"net/http"
"github.com/patrickmn/go-cache"
)
var goCahce *cache.Cache //定义全局变量
func init(){
goCahce = cache.New(5*time.Minute, 60*time.Second)
}
func SetGoCacheData(c *gin.Context){
utilGin := response.Gin{Ctx: c}
var goCacheRequest requests.GoCacheRequest //POST json数据绑定验证
if err := c.ShouldBindJSON(&goCacheRequest); err != nil {
utilGin.Response(http.StatusBadRequest, "参数错误", nil)
return
}
fmt.Println(goCacheRequest.Keyone)
fmt.Println(goCacheRequest.Keytwo)
// 这里的写法是 -1*time.Minute或60*time.Minute 网上的文章真是抄袭,自己真的做过吗 有试过 60或-1 ?
//设置 key-value 并设置默认过期时间
goCahce.Set("go_cache_key_first", goCacheRequest.Keyone, 60*time.Minute) //不能写 60 或-1
// 设置一个不会过期的key,该key不会自动删除,重新更新key或者使用c.Delete("baz")
goCahce.Set("go_cache_key_second", goCacheRequest.Keytwo, -1*time.Minute) //陈波 true
fmt.Println("================")
res := make(map[string]interface{})
res["key_one"] = goCacheRequest.Keyone
res["key_two"] = goCacheRequest.Keytwo
utilGin.Response(0, "success", res)
}
{ //postman里请求 POST格式
“key_one”:“chenhaibo”,
“key_two”:“陈波”
}
{ //返回结果
“code”: 0,
“msg”: “success”,
“data”: {
“key_one”: “chenhaibo”,
“key_two”: “陈波”
}
}
//获取缓存
func GetGoCacheData(c *gin.Context){
utilGin := response.Gin{Ctx: c}
//从缓存获取对应的key的值
value, err := goCahce.Get("go_cache_key_first") // chenhaibo true
value_two, err2 := goCahce.Get("go_cache_key_second")
if err == false{
utilGin.Response(0, "获取go_cache_key_first缓存失败", nil)
return
}
if err2 == false{
utilGin.Response(0, "获取go_cache_key_second缓存失败", nil)
return
}
res := make(map[string]interface{})
res["go_cache_key"] =value
res["go_cache_key_two"] =value_two
utilGin.Response(0, "success", res)
}
效果:
{
“code”: 0,
“msg”: “success”,
“data”: {
“go_cache_key”: “chenhaibo”,
“go_cache_key_two”: “陈波”
}
}
//将上面的设置获取缓存 封装
新建目录和文件 project/utils/nbcache cache.go
package nbcache
import (
"github.com/patrickmn/go-cache"
"time"
)
var cacheAdapter *cache.Cache
func init() {
// 创建一个默认过期时间为5分钟的缓存适配器
// 每60清除一次过期的项目
cacheAdapter = cache.New(5*time.Minute, 60*time.Second)
}
func SetCahce(k string, x interface{}, d time.Duration) {
cacheAdapter.Set(k, x, d)
}
func GetCache(k string) (interface{}, bool) {
return cacheAdapter.Get(k)
}
//设置cache 无时间参数
func SetDefaultCahce(k string, x interface{}) {
cacheAdapter.SetDefault(k, x)
}
//删除 cache
func DeleteCache(k string) {
cacheAdapter.Delete(k)
}
// Add() 加入缓存
func AddCache(k string, x interface{}, d time.Duration) {
cacheAdapter.Add(k, x, d)
}
// IncrementInt() 对已存在的key 值自增n
func IncrementIntCahce(k string, n int) (num int, err error){
return cacheAdapter.IncrementInt(k, n)
}
LoginController.go 新增 方法
import "fkHalo/utils/nbcache"
// 设置缓存
func SetGoCache(c *gin.Context){
utilGin := response.Gin{Ctx: c}
var goCacheRequest requests.GoCacheRequest
if err := c.ShouldBindJSON(&goCacheRequest); err != nil {
utilGin.Response(http.StatusBadRequest, "参数错误", nil)
return
}
fmt.Println(goCacheRequest.Keyone)
fmt.Println(goCacheRequest.Keytwo)
//设置 key-value 并设置默认过期时间
nbcache.SetCahce("go_cache_key_first", goCacheRequest.Keyone, 60*time.Minute)
//设置一个key的值 用于下面 IncrementInt()自增 后获取自增后的值
nbcache.SetCahce("go_cache_increment_int", 2000, 60*time.Minute)
//go-cahce 的 SetDefault()
nbcache.SetCahce("go_cache_set_default", goCacheRequest.Keyone, 60*time.Minute)
// Add() 效果同Set()
nbcache.SetCahce("go_cache_add", goCacheRequest.Keyone, 60*time.Minute)
// 设置一个不会过期的key,该key不会自动删除,重新更新key或者使用c.Delete("baz")
nbcache.SetCahce("go_cache_key_second", goCacheRequest.Keytwo, -1*time.Minute) //陈波 true 只能本函数域使用
fmt.Println("================")
res := make(map[string]interface{})
res["key_one"] = goCacheRequest.Keyone
res["key_two"] = goCacheRequest.Keytwo
utilGin.Response(0, "success", res)
}
postman请求:
{
“key_one”:“chenhaibo gogo”,
“key_two”:“陈波 gogo”
}
响应:
{
“code”: 0,
“msg”: “success”,
“data”: {
“key_one”: “chenhaibo gogo”,
“key_two”: “陈波 gogo”
}
}
//获取缓存
func GetGoCache(c *gin.Context){
utilGin := response.Gin{Ctx: c}
//从缓存获取对应的key的值
value, err := nbcache.GetCache("go_cache_key_first") // chenhaibo true
value_two, err2 := nbcache.GetCache("go_cache_key_second")
if err == false{
utilGin.Response(0, "获取go_cache_key_first缓存失败", nil)
return
}
if err2 == false{
utilGin.Response(0, "获取go_cache_key_second缓存失败", nil)
return
}
//SetDefault()
default_value, _ := nbcache.GetCache("go_cache_set_default")
// Add()
cache_add_value, _ := nbcache.GetCache("go_cache_add")
// delete()
nbcache.DeleteCache("go_cache_add")
cache_add_value_deleted, _ := nbcache.GetCache("go_cache_add")
//IncrementInt() 缓存的值是2000 自增10 =>2010
nums, _ := nbcache.IncrementIntCahce("go_cache_increment_int", 10)
res := make(map[string]interface{})
res["go_cache_key"] =value
res["go_cache_key_two"] =value_two
res["default_value"] =default_value
res["cache_add_value"] =cache_add_value
res["cache_delete_value"] =cache_add_value_deleted
res["cache_increment_int"] =nums
utilGin.Response(0, "success", res)
}
返回结果:
{
“code”: 0,
“msg”: “success”,
“data”: {
“cache_add_value”: “chenhaibo gogo”,
“cache_delete_value”: null,
“cache_increment_int”: 2010,
“default_value”: “chenhaibo gogo”,
“go_cache_key”: “chenhaibo gogo”,
“go_cache_key_two”: “陈波 gogo”
}
}
//当然 还可以储存 slice,切片等格式类型数据
//设置结构体 cache存储和获取 数据
type Permission struct {
Name string `json:"name"`
DisplayName string `json:"display_name"`
GroupName string `json:"group_name"`
}
//cache储存 struct数据
var permissions = []Permission{
{
Name: "A1",
DisplayName: "查看员工列表",
GroupName: "A:员工管理",
},
{
Name: "A2",
DisplayName: "添加员工",
GroupName: "A:员工管理",
},
}
nbcache.AddCache("go_cache_add_struct", permissions, 60*time.Minute)
//cache的 Add() 储存切片 数据
var slice_arr [5]int = [...]int {1, 2, 3, 4, 5}
nbcache.AddCache("go_cache_add_slice", slice_arr, 60*time.Minute)
//cache get struct数据
struct_data, _ := nbcache.GetCache("go_cache_add_struct")
//cache get slice切片
slice_data, _ := nbcache.GetCache("go_cache_add_slice")
var result = map[string]interface{}{
"value": value,
"value_two": value_two,
"default_value": default_value,
"cache_add_value": cache_add_value,
"cache_add_value_deleted": cache_add_value_deleted,
"nums": nums,
"struct_data": struct_data,
"slice_data":slice_data,
}
utilGin.Response(0, "success", result)
效果:
{
“code”: 0,
“msg”: “success”,
“data”: {
“cache_add_value”: “chenhaibo gogo”,
“cache_add_value_deleted”: null,
“default_value”: “chenhaibo gogo”,
“nums”: 2010,
“slice_data”: [
1,
2,
3,
4,
5
],
“struct_data”: [
{
“name”: “A1”,
“display_name”: “查看员工列表”,
“group_name”: “A:员工管理”
},
{
“name”: “A2”,
“display_name”: “添加员工”,
“group_name”: “A:员工管理”
}
],
“value”: “chenhaibo gogo”,
“value_two”: “陈波 gogo”
}
}
// 还有很多不足的地方,还请大家多多指正,谢谢!