郴州建设工程信息网站,wordpress首页缩略图,网站建设客户怎么找,深圳中装建设集团网站文章目录 前情提要 配置缓存前缀 常量缓存中 key 值问题Redis 工具包redis 使用 首先需要自己安装
redis并提前了解相关知识 前情提要
学习项目github地址,有需要可以从这里查看源码
上一部分学习笔记
配置
在 api.ini 中新增 redis 相关配置
...
[redis]
Host 127.0.0.… 文章目录 前情提要 配置缓存前缀 常量缓存中 key 值问题Redis 工具包redis 使用 首先需要自己安装
redis并提前了解相关知识 前情提要
学习项目github地址,有需要可以从这里查看源码
上一部分学习笔记
配置
在 api.ini 中新增 redis 相关配置
...
[redis]
Host 127.0.0.1:6379
Password
MaxIdle 30
MaxActive 30
IdleTimeout 200缓存前缀 常量
打开 pkg/e 目录新建 cache.go写入内容
package econst (CACHE_ARTICLE ARTICLECACHE_TAG TAG
)建立常量保存方便后续管理
缓存中key值问题
新建 service/cathe_service 目录新建 article.go:
// Package cache_service 缓存相关服务单个或多个文章键名
package cache_serviceimport (github.com/kingsill/gin-example/pkg/estrconvstrings
)// Article 定义缓存中可能的文章键名包含的要素
type Article struct {ID intTagID intState intPageNum intPageSize int
}// GetArticleKey 单个文章键名
func (a *Article) GetArticleKey() string {//ARTICLE_1return e.CACHE_ARTICLE _ strconv.Itoa(a.ID)
}// GetArticlesKey 多个文章键名? 一个文章信息更多的键名
func (a *Article) GetArticlesKey() string {keys : []string{e.CACHE_ARTICLE,LIST,}if a.ID 0 {keys append(keys, strconv.Itoa(a.ID))}if a.TagID 0 {keys append(keys, strconv.Itoa(a.TagID))}if a.State 0 {keys append(keys, strconv.Itoa(a.State))}if a.PageNum 0 {keys append(keys, strconv.Itoa(a.PageNum))}if a.PageSize 0 {keys append(keys, strconv.Itoa(a.PageSize))}//ARTICLE_LIST_...return strings.Join(keys, _)
}
同目录新建 tag.go
// Package cache_service 缓存相关服务单个或多个tag键名
package cache_serviceimport (github.com/kingsill/gin-example/pkg/estrconvstrings
)// Tag 定义缓存中可能的Tag键名包含的要素
type Tag struct {ID intName stringState intPageNum intPageSize int
}// GetTagsKey 获取全面的Tag键名
func (t *Tag) GetTagsKey() string {keys : []string{e.CACHE_TAG,LIST,}if t.Name ! {keys append(keys, t.Name)}if t.State 0 {keys append(keys, strconv.Itoa(t.State))}if t.PageNum 0 {keys append(keys, strconv.Itoa(t.PageNum))}if t.PageSize 0 {keys append(keys, strconv.Itoa(t.PageSize))}return strings.Join(keys, _)
}
Redis 工具包
下载 redigo 包帮助使用 redis
go get github.com/gomodule/redigolatest打开 pkg 目录新建 gredis/redis.go写入内容
package gredisimport (encoding/jsongithub.com/gomodule/redigo/redisgithub.com/kingsill/gin-example/pkg/settingtime
)// RedisConn 定义全局变量RedisConn为redis连接池
var RedisConn *redis.Pool// Setup 初始化redis服务
func Setup() error {//实例化RedisConn从setting中加载定义的配置信息RedisConn redis.Pool{MaxIdle: setting.RedisSetting.MaxIdle,MaxActive: setting.RedisSetting.MaxActive,IdleTimeout: setting.RedisSetting.IdleTimeout,Dial: func() (redis.Conn, error) { //创建并配置一个连接c, err : redis.Dial(tcp, setting.RedisSetting.Host)if err ! nil {return nil, err}if setting.RedisSetting.Password ! {if _, err : c.Do(AUTH, setting.RedisSetting.Password); err ! nil {c.Close()return nil, err}}return c, err},TestOnBorrow: func(c redis.Conn, t time.Time) error { //测试连接_, err : c.Do(PING)return err},}return nil
}// Set redis存储的key-value添加数据
func Set(key string, data interface{}, time int) error {conn : RedisConn.Get()defer conn.Close()//将data以json编码为valuevalue, err : json.Marshal(data)if err ! nil {return err}_, err conn.Do(SET, key, value)if err ! nil {return err}//设置过期时间单位为s_, err conn.Do(EXPIRE, key, time)if err ! nil {return err}return nil
}// Exists 检查当前redis中是否有当前key
func Exists(key string) bool {conn : RedisConn.Get()defer conn.Close()exists, err : redis.Bool(conn.Do(EXISTS, key))if err ! nil {return false}return exists
}// Get 获取要查询的key对应的value
func Get(key string) ([]byte, error) {conn : RedisConn.Get()defer conn.Close()reply, err : redis.Bytes(conn.Do(GET, key))if err ! nil {return nil, err}return reply, nil
}// Delete 删除redis中传入的键值对
func Delete(key string) (bool, error) {conn : RedisConn.Get()defer conn.Close()return redis.Bool(conn.Do(DEL, key))
}// LikeDeletes 删除所有包含指定键名的键值对
func LikeDeletes(key string) error {conn : RedisConn.Get()defer conn.Close()keys, err : redis.Strings(conn.Do(KEYS, *key*))if err ! nil {return err}for _, key : range keys {_, err Delete(key)if err ! nil {return err}}return nil
}
redis 使用
在原来的逻辑中以检索文件为例我们直接在 mysql 中检索数据现在我们在之前新增在 redis 中搜索如果没有再跳转到 mysql
并且我们将检索封装成一个函数代码阅读更加直观 打开 service 目录新建 article_service/article.go
package article_serviceimport (encoding/jsongithub.com/kingsill/gin-example/modelsgithub.com/kingsill/gin-example/pkg/gredisgithub.com/kingsill/gin-example/pkg/logginggithub.com/kingsill/gin-example/service/cache_service
)// Article 建立文章结构体方便信息存储及与gorm的互动
type Article struct {ID intTagID intTitle stringDesc stringContent stringCoverImageUrl stringState intCreatedBy stringModifiedBy stringPageNum intPageSize int
}// Add 新建文章服务
func (a *Article) Add() error {//创建article实例article : map[string]interface{}{tag_id: a.TagID,title: a.Title,desc: a.Desc,content: a.Content,created_by: a.CreatedBy,cover_image_url: a.CoverImageUrl,state: a.State,}if err : models.AddArticle(article); err ! nil {return err}return nil
}// Edit 编辑文章服务
func (a *Article) Edit() error {return models.EditArticle(a.ID, map[string]interface{}{tag_id: a.TagID,title: a.Title,desc: a.Desc,content: a.Content,cover_image_url: a.CoverImageUrl,state: a.State,modified_by: a.ModifiedBy,})
}// Get 查询文章服务
func (a *Article) Get() (*models.Article, error) {var cacheArticle *models.Article//推算文章键名cache : cache_service.Article{ID: a.ID}key : cache.GetArticleKey()//根据文章键名在redis中查询if gredis.Exists(key) {data, err : gredis.Get(key)if err ! nil {logging.Info(err)} else {json.Unmarshal(data, cacheArticle)return cacheArticle, nil}}//redis中没有查询到则在mysql中查询article, err : models.GetArticle(a.ID)if err ! nil {return nil, err}//在redis中存储该组键值对并设置过期时间gredis.Set(key, article, 3600)return article, nil
}// GetAll 类比上面 get 进行理解
func (a *Article) GetAll() ([]*models.Article, error) {var (articles, cacheArticles []*models.Article)cache : cache_service.Article{TagID: a.TagID,State: a.State,PageNum: a.PageNum,PageSize: a.PageSize,}key : cache.GetArticlesKey()if gredis.Exists(key) {data, err : gredis.Get(key)if err ! nil {logging.Info(err)} else {json.Unmarshal(data, cacheArticles)return cacheArticles, nil}}articles, err : models.GetArticles(a.PageNum, a.PageSize, a.getMaps())if err ! nil {return nil, err}gredis.Set(key, articles, 3600)return articles, nil
}// Delete 简单对之前函数的包装调用
func (a *Article) Delete() error {return models.DeleteArticle(a.ID)
}func (a *Article) ExistByID() (bool, error) {return models.ExistArticleByID(a.ID)
}func (a *Article) Count() (int, error) {return models.GetArticleTotal(a.getMaps())
}// 构建适用于多个文章查询等的条件映射
func (a *Article) getMaps() map[string]interface{} {maps : make(map[string]interface{})maps[deleted_on] 0if a.State ! -1 {maps[state] a.State}if a.TagID ! -1 {maps[tag_id] a.TagID}return maps
}
过程中可能会对之前的函数进行一定小小的修改根据报错进行修改即可
同样的大家可以自行建立tag_service/tag.go