|
|
package DaoCache
|
|
|
|
|
|
import (
|
|
|
"dsSso/Const/ErrorConst"
|
|
|
"dsSso/Model"
|
|
|
"dsSso/Utils/CommonUtil"
|
|
|
"dsSso/Utils/DbUtil"
|
|
|
"dsSso/Utils/LogUtil"
|
|
|
"dsSso/Utils/RedisUtil"
|
|
|
"fmt"
|
|
|
"github.com/go-redis/redis/v7"
|
|
|
"reflect"
|
|
|
"strconv"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
var db = DbUtil.Engine
|
|
|
|
|
|
/**
|
|
|
功能:优先从缓存读取,检查到缺失的,就从数据库读取,然后两个结果集拼接后返回,同时将缺失的缓存补全
|
|
|
作者:黄海
|
|
|
时间:2020-02-05
|
|
|
*/
|
|
|
func GetListByIds(ids []string, m Model.Selector) []map[string]interface{} {
|
|
|
//1、第一步从缓存读取
|
|
|
list, notExistsIds := batchReadRedis(ids, m.RedisPrefix)
|
|
|
//2、如果有一些ID在缓存中不存在,那么需要从数据库中查询,然后填充到缓存中
|
|
|
if notExistsIds != nil && len(notExistsIds) > 0 {
|
|
|
//从数据库中获取缺失的数据
|
|
|
lostCacheList := fromDb(notExistsIds, m)
|
|
|
//缓存写入
|
|
|
batchWriteRedis(lostCacheList, m)
|
|
|
//合并两个结果集
|
|
|
for i := 0; i < len(lostCacheList); i++ {
|
|
|
list = append(list, lostCacheList[i])
|
|
|
}
|
|
|
}
|
|
|
return list
|
|
|
}
|
|
|
|
|
|
/*===================以下为内部函数,用于扩展从REDIS缓存中查询===========================*/
|
|
|
func fromDb(ids []string, m Model.Selector) []map[string]interface{} {
|
|
|
tableName := m.TableName
|
|
|
pkField := m.PkField
|
|
|
//查询数据库
|
|
|
var idsStr = ""
|
|
|
for i := 0; i < len(ids); i++ {
|
|
|
idsStr = idsStr + "," + ids[i]
|
|
|
}
|
|
|
if len(idsStr) > 0 {
|
|
|
idsStr = idsStr[1:]
|
|
|
}
|
|
|
results, err := db.SQL(`select * from `+tableName+` where find_in_set(`+pkField+`,?)`, idsStr).Query().List()
|
|
|
if err != nil {
|
|
|
LogUtil.Error(ErrorConst.SqlQueryError, "从数据库中读取数据失败:"+err.Error())
|
|
|
}
|
|
|
return results
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
功能:批量写入缓存
|
|
|
作者:黄海
|
|
|
时间:2020-02-05
|
|
|
*/
|
|
|
func batchWriteRedis(list []map[string]interface{}, m Model.Selector) {
|
|
|
pkField := m.PkField
|
|
|
prefix := m.RedisPrefix
|
|
|
//声明管道
|
|
|
pipe := RedisUtil.RedisClient.Pipeline()
|
|
|
for i := 0; i < len(list); i++ {
|
|
|
bean := list[i]
|
|
|
var pkSuffix = ""
|
|
|
switch bean[pkField].(type) {
|
|
|
case string:
|
|
|
pkSuffix = bean[pkField].(string)
|
|
|
case int64:
|
|
|
pkSuffix = strconv.FormatInt(reflect.ValueOf(bean[pkField]).Int(), 10)
|
|
|
}
|
|
|
key := prefix + pkSuffix
|
|
|
pipe.HSet(key, bean)
|
|
|
pipe.Expire(key, 24*time.Hour)
|
|
|
}
|
|
|
//执行管道
|
|
|
pipe.Exec()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
功能:从REDIS中批量获取指定ID的列表信息
|
|
|
作者:黄海
|
|
|
时间:2020-02-05
|
|
|
*/
|
|
|
func batchReadRedis(ids []string, prefix string) ([]map[string]interface{}, []string) {
|
|
|
//1、创建管道
|
|
|
var list []*redis.StringStringMapCmd
|
|
|
pipe := RedisUtil.RedisClient.Pipeline()
|
|
|
for i := 0; i < len(ids); i++ {
|
|
|
list = append(list, pipe.HGetAll(prefix+ids[i]))
|
|
|
}
|
|
|
//2、执行管道
|
|
|
_, err := pipe.Exec()
|
|
|
if err != nil {
|
|
|
LogUtil.Error(ErrorConst.SqlQueryError, err.Error())
|
|
|
}
|
|
|
//存在于缓存中的数据
|
|
|
var existList []map[string]interface{}
|
|
|
//3、输出结果
|
|
|
//不存在的主键有哪些
|
|
|
var notExistsIds []string
|
|
|
for i := 0; i < len(list); i++ {
|
|
|
_bean := list[i].Val()
|
|
|
if len(_bean) > 0 {
|
|
|
//将values转成Interface{},其实这个锅 Golang是不背的,因为redis中hset写入的整数,取出来hget也是字符串~
|
|
|
n := CommonUtil.ConvertMapStringToMapInterface(_bean)
|
|
|
//找到了加到返回值列表中去
|
|
|
existList = append(existList, n)
|
|
|
} else {
|
|
|
notExistsIds = append(notExistsIds, ids[i])
|
|
|
}
|
|
|
}
|
|
|
//返回值
|
|
|
return existList, notExistsIds
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
功能:将指定的SQL语句计算分页的SQL
|
|
|
作者:黄海
|
|
|
时间:2020-03-25
|
|
|
*/
|
|
|
func PageData(baseSql string, model Model.Selector, args ...interface{}) ([]map[string]interface{}, int32) {
|
|
|
//条件查询语句
|
|
|
conditionSql := fmt.Sprintf("%s %s %s", " order by ", model.PkField, " limit ? offset ? ")
|
|
|
//分页的语句
|
|
|
pageSql := fmt.Sprintf("%s %s", baseSql, conditionSql)
|
|
|
//分页数据
|
|
|
list, err := db.SQL(pageSql, args...).Query().List()
|
|
|
if err != nil {
|
|
|
LogUtil.Error(ErrorConst.SqlQueryError, err.Error())
|
|
|
}
|
|
|
//总数
|
|
|
list2, err := db.SQL(baseSql, args...).Query().List()
|
|
|
if err != nil {
|
|
|
LogUtil.Error(ErrorConst.SqlQueryError, err.Error())
|
|
|
}
|
|
|
|
|
|
//有哪些ids?
|
|
|
var ids = CommonUtil.Ids(list, model.PkField)
|
|
|
//-->缓存层-->数据库-->缓存
|
|
|
list = GetListByIds(ids, model)
|
|
|
return list, int32(len(list2))
|
|
|
}
|