命令记不住

登陆

WebGin 简单框架 - dao/redis

WebGin简单框架-dao/redis

Web目录结构

C:.
├─.idea
│  └─dictionaries
├─controllers
├─dao
│  ├─mysql
│  └─redis
├─dist
│  └─static
│      ├─css
│      ├─fonts
│      └─js
├─logger
├─logic
├─models
├─pkg
│  ├─myJWT
│  └─snowflake
├─routers
├─setting
└─main.g

1.redis.go

redis.go

package redis

import (
	"fmt"
	"webapp/setting"

	"github.com/spf13/viper"

	"github.com/go-redis/redis"
)

var (
	Client *redis.Client
)

// 初始化连接
func Init() (err error) {
	//
	Client = redis.NewClient(&redis.Options{
		//Addr: fmt.Sprintf("%s:%d", viper.GetString("redis.host"), viper.GetInt("redis.port")),
		Addr: fmt.Sprintf("%s:%d", setting.Conf.RedisConfig.Host, setting.Conf.RedisConfig.Port),
		DB:   viper.GetInt("redis.db"), // use default DB
	})

	_, err = Client.Ping().Result()
	return
}

2.keys.go

keys.go

package redis

const (
	AppPrefix = "xiaodebu:"

	KeyQuestionTimeZSet  = AppPrefix + "question:time:"  // 发布时间作为分数的问题ZSet
	KeyQuestionScoreZSet = AppPrefix + "question:score:" // 投票累计作为分数的问题ZSet

	KeyQuestionVotedSetPrefix    = AppPrefix + "question:voted:"    // 某个问题已经投票过的用户Set
	KeyQuestionInfoHashPrefix    = AppPrefix + "question:info:"     // hash,存储问题的基础信息
	KeyCategoryQuestionSetPrefix = AppPrefix + "question:category:" // 问题的分类
)

3.question.go

question.go

package redis

import (
	"time"

	"github.com/go-redis/redis"
)

const (
	OneWeekInSeconds = 7 * 24 * 3600
	VoteScore        = 432 // 200张赞成票能给帖子续一天 86400/200=432
	PerAge           = 20
)

// QuestionVoteUp 为提问投票
func QuestionVoteUp(questionID, userID string) (err error) {
	votedKey := KeyQuestionVotedSetPrefix + questionID
	scoreKey := KeyQuestionScoreZSet
	questionInfoKey := KeyQuestionInfoHashPrefix + questionID
	// 记录投票相关数据
	// 确保当前用户没有给该问题投过票
	if !Client.SIsMember(votedKey, userID).Val() {
		// redis事务操作
		pipe := Client.TxPipeline()
		pipe.SAdd(votedKey, userID)
		pipe.ZIncrBy(scoreKey, VoteScore, questionID)
		pipe.HIncrBy(questionInfoKey, "votes", 1)
		_, err = pipe.Exec()
		return
	}
	return
}

// CreateQuestion 使用hash存储提问信息
func CreateQuestion(questionID, userID, caption, content string) (err error) {
	now := float64(time.Now().Unix())
	votedKey := KeyQuestionVotedSetPrefix + questionID
	infoKey := KeyQuestionInfoHashPrefix + questionID
	scoreKey := KeyQuestionScoreZSet
	timeKey := KeyQuestionTimeZSet

	pipeline := Client.Pipeline()
	pipeline.SAdd(votedKey, userID)
	pipeline.Expire(votedKey, time.Second*OneWeekInSeconds)
	fields := map[string]interface{}{
		"caption":     caption,
		"content":     content,
		"question:id": questionID,
		"user:id":     userID,
		"time":        now,
		"votes":       1,
		"comments":    0,
	}
	pipeline.HMSet(infoKey, fields)  // 存hash
	pipeline.ZAdd(scoreKey, redis.Z{ // 往问题分数的ZSet添加当前的问题
		Score:  now + VoteScore,
		Member: questionID,
	})
	pipeline.ZAdd(timeKey, redis.Z{ // 往问题时间ZSet添加当前的问题
		Score:  now,
		Member: questionID,
	})
	_, err = pipeline.Exec()
	return
}

// 查询问题排行榜
// 1.按发布时间排序
// 2.按分数(热度)排序

// GetQuestion 从key中分页取出问题
func GetQuestion(key string, page int64) []map[string]string {
	start := (page - 1) * PerAge // 0
	end := start + PerAge - 1    // 19
	ids := Client.ZRevRange(key, start, end).Val()
	list := make([]map[string]string, 0, len(ids))
	pipe := Client.Pipeline()
	for _, id := range ids {
		pipe.HGetAll(KeyQuestionInfoHashPrefix + id)
	}
	c, err := pipe.Exec()
	if err != nil {
		return nil
	}
	for _, cm := range c {
		v, err := cm.(*redis.StringStringMapCmd).Result()
		if err != nil {
			continue
		}
		list = append(list, v)
	}
	return list
}

// GetCategoryQuestion 分时间或者分数取出分页的帖子
func GetCategoryQuestion(categoryName, orderKey string, page int64) []map[string]string {
	key := orderKey + categoryName // 创建缓存键
	categoryKey := KeyCategoryQuestionSetPrefix + categoryName
	// 对categoryKey 和 问题时间 进行取交集计算,并把结果缓存到key中(60秒)
	if Client.Exists(key).Val() < 1 {
		Client.ZInterStore(key, redis.ZStore{
			Aggregate: "MAX",
		}, categoryKey, orderKey)

		Client.Expire(key, 60*time.Second)
	}
	return GetQuestion(key, page)
}

//GetCategoryQuestion("xuexi", KeyQuestionTimeZSet)  // 学习分区按发布时间排序

//GetCategoryQuestion("qinggan", KeyQuestionScoreZSet)// 情感分区按分数排序
推荐阅读