目录
一、项目结构
二、服务器配置
1、Redis在配置文件中的配置情况如下:config.json
2、读取配置文件初始化服务器配置:config.go
3、Redis连接对象实例化:redis.go
4、将Session存储方式设置为Redis:main.go
5、在Controller家口中使用redis:statis_controller.go
6、在main入口中注册:main.go
三、浏览器请求测试
四、过程踩坑
1、parse时间转换
2、iris版本
五、完整代码
1、config.json
2、config.go
3、engin.go
4、redis.go
5、statis_controller.go
6、statis_service.go
7、main.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.Redisiris.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 []stringif 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 int64switch 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.Portapp.Run(iris.Addr(addr), //在端口8080进行监听iris.WithoutServerError(iris.ErrServerClosed), //无服务错误提示iris.WithOptimizations, //对json数据序列化更快的配置)
}//构建App
func newApp() *iris.Application {app := iris.New()//设置日志级别 开发阶段为debugapp.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) {//启用sessionsessManager := sessions.New(sessions.Config{Cookie: "sessioncookie",Expires: 24 * time.Hour,})//获取redis实例redis := datasource.NewRedis()//设置session的同步位置为redissessManager.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))
}