先创建一个cache文件夹和cache.go
设计好缓存模块的接口
package cache
import "time"
type CacheContract interface {
Put(key string, value string, ttl time.Duration) error
Get(key string) (string, error)
}
基于redis实现缓存
package redisCache
import (
"context"
"myGin/redis"
"time"
)
type redisCache struct {
}
func NewRedisCache() *redisCache {
return &redisCache{}
}
func (r redisCache) Put(key string, value string, ttl time.Duration) error {
//TODO implement me
_, err := redis.Client().Set(context.TODO(), key, value, ttl).Result()
return err
}
func (r redisCache) Get(key string) (string, error) {
//TODO implement me
return redis.Client().Get(context.TODO(), key).Result()
}
基于file实现缓存
先创建storage文件夹
package fileCache
import (
"crypto/md5"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"time"
)
type fileCache struct {
}
type structure struct {
Data string `json:"data"`
Expire int `json:"expire"`
}
func NewFileCache() *fileCache {
return &fileCache{}
}
func (f fileCache) Put(key string, value string, ttl time.Duration) error {
//TODO implement me
//key的md5作为文件名
file, err := os.OpenFile("storage/"+fmt.Sprintf("%x", md5.Sum([]byte(key))), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer file.Close()
var v structure
v.Data = value
//设置过期时间
if ttl == 0 {
v.Expire = 0
} else {
v.Expire = int(time.Now().Add(ttl).Unix())
}
jsonStr, err := json.Marshal(v)
if err != nil {
return err
}
_, err = file.Write(jsonStr)
return err
}
func (f fileCache) Get(key string) (string, error) {
//TODO implement me
filePath := "storage/" + fmt.Sprintf("%x", md5.Sum([]byte(key)))
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
data, err := ioutil.ReadAll(file)
if err != nil {
return "", err
}
var v structure
err = json.Unmarshal(data, &v)
if err != nil {
return "", err
}
now := time.Now().Unix()
//判断过期时间
if v.Expire != 0 && (now > int64(v.Expire)) {
//删除过期文件
defer func(f *os.File, ff string) {
f.Close()
os.Remove(ff)
}(file, filePath)
return "", errors.New("缓存已超时")
}
return v.Data, err
}
使用工厂模式来切换驱动
package cache
import (
"myGin/cache/fileCache"
"myGin/cache/redisCache"
"time"
)
type CacheContract interface {
Put(key string, value string, ttl time.Duration) error
Get(key string) (string, error)
}
func Cache(driver string) CacheContract {
switch driver {
case "redis":
return redisCache.NewRedisCache()
case "file":
return fileCache.NewFileCache()
}
return redisCache.NewRedisCache()
}
调用
package main
import (
"myGin/cache"
"time"
)
func main() {
c := cache.Cache("file")
c.Put("peter", "nice", 1*time.Minute)
c.Get("peter")
}