目錄
1、Redis在配置文件中的配置情況如下:config.json
4、將Session存儲方式設置爲Redis:main.go
5、在Controller家口中使用redis:statis_controller.go
項目搭建過程參考:
- Iris搭建一個完整的go web項目過程——管理員登錄功能開發:https://blog.csdn.net/qq_38151401/article/details/105907576
一、項目結構
二、服務器配置
在實戰項目中使用Redis功能,首先需要進行Redis配置。本實戰項目中,關與Redis的配置項包含:連接類型、地址、端口、公共前綴。以上配置項被定義包含在Iris框架的redis包中的Config結構體中,主要包含如下內容:
- Network: 連接類型。TCP
- Addr: 即將連接的Redis服務主機IP。本實戰項目的Redis服務部署在本機,因此主機ip爲127.0.0.1。Redis服務默認端口爲6379。因此,Addr在本實例項目中的配置值爲127.0.0.1:6379。
- Password: 登陸Redis的密碼。默認配置爲空。
- Prefix:爲要保存的所有的內容設置公共的前綴。默認設置爲空。
- IdleTimeout:設置Redis中的生效時長。這裏我們設置time.Duration(24) * time.Hour。在實際的開發過程中,開發者可以根據自己的需求設定Redis的生效時長。
此處僅展示redis的配置
1、Redis在配置文件中的配置情況如下:config.json
2、讀取配置文件初始化服務器配置:config.go
3、Redis連接對象實例化:redis.go
我們通過讀取配置文件完成配置內容的讀取,利用Redis配置信息實例化Redis對象,Redis實例化如下:
4、將Session存儲方式設置爲Redis:main.go
5、在Controller家口中使用redis:statis_controller.go
6、在main入口中註冊:main.go
三、瀏覽器請求測試
命令行查看:
redis desktop manager查看:
四、過程踩坑
這個過程才了兩個坑:
1、parse時間轉換
在用Go語言對時間字符串進行parse的時候踩坑,Golang time error: month out of range
經過試驗,“2016-12-25 00:00:00”這種格式是可以的,“2016-12-25“這種格式在試驗的時候可以,然而在某些情況卻會報錯,比如說當parse”2018-01-28”的時候,就會報 “month out of range”.原因不清楚,需要繼續看源碼研究,所以以後parse的時候,使用time模塊自帶的那幾種格式,和“2016-12-25 00:00:00”這種格式都是ok的, 如下。
-
date, err := time.Parse("2006-01-02 15:04:05", "2020-05-03 19:32:15")
而這樣寫:d, err := time.Parse("2006-01-02", "2020-05-03")有時候正確,有時候錯誤,很迷啊【month out of range】
2、iris版本
Iris+redis之版本踩坑,之前看的教程,引入redis的方法是:"github.com/kataras/iris/sessions/sessiondb/redis/service"
但是我試了的是V11和V12版本的iris,都不存在這個包!!!!坑人的地方在於,教程是2019件8月份之前的,可能使用的iris版本是V10之前的,之後已經沒有service這個包了
可以看到v10的iris還是有這個包的,並且Config就定義config.go中;
而之後版本已經不存在service包了,Config直接定義在database.go中,並且具體的定義也有改動~~~
五、完整代碼
1、config.json
{
"app_name": "CmsProject",
"port": "9000",
"static_path": "/manage/static",
"redis": {
"network": "tcp",
"addr": "106.15.202.182",
"port": "6379",
"prefix": ""
},
"mode": "dev"
}
2、config.go
/**
服務端配置
*/
type AppConfig struct {
AppName string `json:"app_name"`
Port string `json:"port"`
StaticPath string `json:"static_path"`
Mode string `json:"mode"`
Redis Redis `json:"redis"`
}
/**
* Redis 配置
*/
type Redis struct {
NetWork string `json:"net_work"`
Addr string `json:"addr"`
Port string `json:"port"`
Password string `json:"password"`
Prefix string `json:"prefix"`
}
var ServConfig AppConfig
//初始化服務器配置
func InitConfig()*AppConfig {
file,err := os.Open("config.json")
if err != nil {
panic(err.Error())
}
decoder := json.NewDecoder(file)
conf := AppConfig{}
err = decoder.Decode(&conf)
if err != nil {
panic(err.Error())
}
return &conf
}
3、engin.go
import (
"QianfengCmsProject/models"
_ "github.com/go-sql-driver/mysql" //不能忘記導入
"github.com/go-xorm/xorm"
)
func NewMysqlEngine() *xorm.Engine {
engine, err := xorm.NewEngine("mysql", "root:123456@/iris?charset=utf8")
err = engine.Sync2(
/*new(models.Permission),*/
/*new(models.City),*/
new(models.Admin),
/*new(models.AdminPermission),
new(models.User),
new(models.UserOrder),*/
)
if err != nil {
panic(err.Error())
}
//設置顯示sql語句
engine.ShowSQL(true)
engine.SetMaxOpenConns(10)
return engine
}
4、redis.go
import (
"QianfengCmsProject/config"
iris "github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/sessions/sessiondb/redis"
)
//返回redis實例
func NewRedis() *redis.Database{
var database *redis.Database
//項目配置
cmsConfig := config.InitConfig()
if cmsConfig !=nil{
iris.New().Logger().Info(" hello ")
rd := cmsConfig.Redis
iris.New().Logger().Info(rd)
database = redis.New(redis.Config{
Network: rd.NetWork,
Addr: rd.Addr + ":" + rd.Port,
Password: rd.Password,
Database: "",
MaxActive: 10,
Timeout: redis.DefaultRedisTimeout,
Prefix: rd.Prefix,
})
}else {
iris.New().Logger().Info(" hello error ")
}
return database
}
5、statis_controller.go
type StatisController struct {
//iris框架自動爲每個請求都綁定上下文對象:可作爲接受參數
Ctx iris.Context
//admin功能實體:引入Service接口
Service service.StatisService
//session對象:存儲session信息
Session *sessions.Session
}
var (
ADMINMODULE = "ADMIN_"
USERMODULE = "USER_"
ORDERMODULE = "ORDER_"
)
/* /statis/admin/2019-03-10/count*/
func (sc *StatisController) GetCount() mvc.Result {
path := sc.Ctx.Path()
var pathSlice []string
if path != "" {
pathSlice = strings.Split(path, "/")
}
//不符合請求格式
if len(pathSlice) != 5 {
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_FAIL,
"count": 0,
},
}
}
//將最前面的去掉
pathSlice = pathSlice[1:]
model := pathSlice[1]
date := pathSlice[2]
var result int64
switch model {
case "user":
fmt.Println("GetCount--->user")
case "order":
fmt.Println("order--->user")
case "admin":
adminStatis := sc.Session.Get(ADMINMODULE + date)
if adminStatis != nil {
adminStatis = adminStatis.(float64)
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_OK,
"count": adminStatis,
},
}
} else {
result = sc.Service.GetAdminDailyCount(date)
sc.Session.Set(ADMINMODULE, result)
}
}
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_OK,
"count": result,
},
}
}
6、statis_service.go
//統計功能模塊接口標準
type StatisService interface {
GetAdminDailyCount(date string) int64
}
//統計功能服務實現結構體
type statisService struct {
Engin *xorm.Engine
}
func NewStatisService(engin *xorm.Engine) StatisService {
return &statisService{
Engin: engin,
}
}
func (ss *statisService) GetAdminDailyCount(date string) int64 {
if date == "NaN-NaN-NaN" { //當日增長數據請求
date = time.Now().Format("2006-01-02")
}
//查詢如期data格式解析
startDate, err := time.Parse("2006-01-02 15:04:05", date+" 00:00:00")
if err != nil {
return 0
}
endDate := startDate.AddDate(0, 0, 1)
result, err := ss.Engin.Where("create_time between ? and ? and status = 0",
startDate.Format("2006-01-02 15:04:05"),
endDate.Format("2006-01-02 15:04:05")).Count(models.Admin{})
if err != nil {
return 0
}
fmt.Println(result)
return result
}
7、main.go
func main() {
app := newApp()
//應用App設置
configation(app)
//路由設置
mvcHandle(app)
config := config.InitConfig()
addr := "localhost:" + config.Port
app.Run(
iris.Addr(addr), //在端口8080進行監聽
iris.WithoutServerError(iris.ErrServerClosed), //無服務錯誤提示
iris.WithOptimizations, //對json數據序列化更快的配置
)
}
//構建App
func newApp() *iris.Application {
app := iris.New()
//設置日誌級別 開發階段爲debug
app.Logger().SetLevel("debug")
//註冊靜態資源
app.HandleDir("/static", "./static")
app.HandleDir("/manage/static", "./static")
app.HandleDir("/img", "./static/img")
//註冊視圖文件
app.RegisterView(iris.HTML("./static", ".html"))
app.Get("/", func(context context.Context) {
context.View("index.html")
})
return app
}
/**
* 項目設置
*/
func configation(app *iris.Application) {
//配置 字符編碼
app.Configure(iris.WithConfiguration(iris.Configuration{
Charset: "UTF-8",
}))
//錯誤配置
//未發現錯誤
app.OnErrorCode(iris.StatusNotFound, func(context context.Context) {
context.JSON(iris.Map{
"errmsg": iris.StatusNotFound,
"msg": " not found ",
"data": iris.Map{},
})
})
app.OnErrorCode(iris.StatusInternalServerError, func(context context.Context) {
context.JSON(iris.Map{
"errmsg": iris.StatusInternalServerError,
"msg": " interal error ",
"data": iris.Map{},
})
})
}
//MVC 架構模式處理
func mvcHandle(app *iris.Application) {
//啓用session
sessManager := sessions.New(sessions.Config{
Cookie: "sessioncookie",
Expires: 24 * time.Hour,
})
//獲取redis實例
redis := datasource.NewRedis()
//設置session的同步位置爲redis
sessManager.UseDatabase(redis)
//實例化mysql數據庫引擎
engine := datasource.NewMysqlEngine()
//管理員模塊功能
adminService := service.NewAdminService(engine)
admin := mvc.New(app.Party("/admin")) //設置路由組
admin.Register(
adminService,
sessManager.Start,
)
//通過mvc的Handle方法進行控制器的指定
admin.Handle(new(controller.AdminController))
//統計功能模塊
statisService := service.NewStatisService(engine)
statis := mvc.New(app.Party("/statis/{model}/{date}/"))
statis.Register(
statisService,
sessManager.Start,
)
statis.Handle(new(controller.StatisController))
}