前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于框架gin+xorm搭建的MVC项目

基于框架gin+xorm搭建的MVC项目

作者头像
李海彬
发布2019-05-08 11:38:59
1.9K0
发布2019-05-08 11:38:59
举报
文章被收录于专栏:Golang语言社区Golang语言社区

作者:mydev 来源:简书

go-gin-mvc 项目地址:https://github.com/mydevc/go-gin-mvc

基于golang语言的gin-gonic/gin 框架搭建的MVC架构的基础项目空架子供初学者学习参考,如果你是从PHP语言转过来的,一定会非常喜欢这个架构。

此项目集成了小型网站开发常用的功能:

1、基于redis连接池存储的cache操作;

utils/helper.go

代码语言:javascript
复制
 1// 建立连接池
 2RedisPool = &redis.Pool{
 3    MaxIdle:     max_idle,
 4    MaxActive:   max_active,
 5    IdleTimeout: idle_timeout,
 6    Wait:        true,
 7    Dial: func() (redis.Conn, error) {
 8        con, err := redis.Dial("tcp", host,
 9            //redis.DialPassword(conf["Password"].(string)),
10            redis.DialDatabase(database),
11            redis.DialConnectTimeout(timeout),
12            redis.DialReadTimeout(timeout),
13            redis.DialWriteTimeout(timeout))
14        if err != nil {
15            return nil, err
16        }
17        return con, nil
18    },
19}

ctrls/test_controller.go

代码语言:javascript
复制
 1//Redis测试
 2func RedisSetAction(ctx *gin.Context) {
 3    rds := utils.RedisPool.Get();
 4    count, _ := redis.Int(rds.Do("GET", "count"))
 5    count++
 6    rds.Do("SET", "count", count)
 7    ctx.JSON(200, gin.H{
 8        "message": count,
 9    })
10}

2、基于redis连接池存储的session操作;

注意这里的连接池是独立于cache操作redis的连接池,需单独配置参数。

代码语言:javascript
复制
1//不用连接池
2//store,err:=redis.NewStore(10,"tcp","rs1.baidu.com:6379","",[]byte("asfajfa;lskjr2"))
3//使用连接池
4store, err := redis.NewStoreWithPool(utils.RedisPool, []byte("as&8(0fajfa;lskjr2"))

session配置

代码语言:javascript
复制
 1store, err := redis.NewStoreWithPool(utils.RedisPool, []byte("as&8(0fajfa;lskjr2"))
 2store.Options(sessions.Options{
 3    "/",
 4    domain,
 5    maxage,
 6    false, //https 时使用
 7    true,  //true:JS脚本无法获取cookie信息
 8})
 9if err != nil {
10    // Handle the error. Probably bail out if we can't connect.
11    fmt.Println("redis.NewStore error")
12}
13Router.Use(sessions.Sessions(session_name, store))

Sesssion测试

代码语言:javascript
复制
 1//Sesssion测试
 2func SessionAction(ctx *gin.Context) {
 3    session := sessions.Default(ctx)
 4    var count int
 5    v := session.Get("count")
 6    if v == nil {
 7        count = 0
 8    } else {
 9        count = v.(int)
10        count += 1
11    }
12    session.Set("count", count)
13    session.Save()
14    ctx.JSON(200, gin.H{"count": count})
15}

3、基于xorm的数据库操作,主从分离配置,支持多从库配置,鲜活连接定时PING操作,集成xorm/cmd;

部分代码展示,完整代码见:models/orm.go

代码语言:javascript
复制
 1//从库添加
 2slaves := utils.Config.Section("mysql_slave").Keys()
 3for _, s_dsn := range slaves {
 4    _dbs, err := xorm.NewEngine("mysql", s_dsn.String())
 5    _dbs.SetMaxIdleConns(10)
 6    _dbs.SetMaxOpenConns(200)
 7    _dbs.ShowSQL(true)
 8    _dbs.ShowExecTime(true)
 9
10    if err!=nil {
11        fmt.Println(err)
12    }else{
13        dbs = append(dbs, _dbs)
14    }
15}

4、基于rabbitmq的队列应用,注意生产者与消费者队列名称的一致性

多个任务可发送到一个队列,也可以灵活应用一个队列一个任务; 生产者与消费者消息传递的是序列化的结构体,结构体由生产者提供,并自行反序列化操作;

- 消费者: console/queue_daemon.go (队列需要单独控制台命令启动,与http服务独立[避免相互影响];)

代码语言:javascript
复制
 1subscriber := new(jobs.Subscribe)
 2forever := make(chan bool)
 3q := queue.NewQueue()
 4//队列执行的任务需要注册方可执行
 5q.PushJob("Dosome",jobs.HandlerFunc(subscriber.Dosome))
 6//q.PushJob("Fusome",jobs.HandlerFunc(subscriber.Fusome))
 7//提前规划好队列,可按延时时间来划分。可多个任务由一个队列来执行,也可以一个任务一个队列,一个队列可启动多个消费者
 8go q.NewShareQueue("SomeQueue")
 9//go q.NewShareQueue("SomeQueue")
10//go q.NewShareQueue("SomeQueue")
11defer q.Close()
12<-forever

- 控制台生产者(这里仅测试使用,正式应用一般在web代码中)

console/send_single.go

代码语言:javascript
复制
1forever := make(chan bool)
2go func() {
3    for i := 0; i < 1000000; i++ {
4        queue.NewSender("SomeQueue", "Dosome", jobs.Subscribe{Name: "We are doing..." + strconv.Itoa(i)}).Send()
5    }
6}()
7defer queue.SendConn.Close()
8<-forever

- WEB测试生产者: http://localhost:8080/queue

代码语言:javascript
复制
1//队列生产者测试
2func QueueAction(ctx *gin.Context)  {
3    queue.NewSender("SomeQueue", "Dosome", jobs.Subscribe{Name: "We are doing..."}).Send()
4}

5、csrf防跨站攻击

此功能集成此中间件完成点这里,更多中间件。 这里要重点说一下,utrack/gin-csrf这个中间件没有加白名单机制排除一些例外,这在实际应用中是很常见的,尤其是对外合作接口中。 我把此中间件代码集成到我自己的代码中来,把白名单功能补上了。这里直接用包名+函数名来定位,在配置文件conf/csrf_except.ini中配置, key值随意,不空,不重复即可,因不是实时读取,修改后需要重启web服务才生效。

- 应用代码route/router.go

代码语言:javascript
复制
1Router.Use(csrf.Middleware(csrf.Options{
2    Secret: csrfscret,
3    ErrorFunc: func(c *gin.Context) {
4        c.String(400, "CSRF token mismatch")
5        c.Abort()
6    },
7}))

- 补丁代码:middleware/csrf/csrf.go

代码语言:javascript
复制
 1fn := c.HandlerName();
 2fn = fn[strings.LastIndex(fn, "/"):]
 3
 4for _, action := range IgnoreAction {
 5    if (strings.Contains(fn, action)) {
 6        fmt.Println(action)
 7        c.Next()
 8        return
 9    }
10}

6、数据验证,可自定义友好错误提示,更多实例参考;

ctrls/users/user_controller.go 中 UserAddAction()

代码语言:javascript
复制
 1//参数检验
 2rules := govalidator.MapData{
 3    "name": []string{"required", "between:3,8"},
 4    "age":  []string{"digits:11"},
 5}
 6
 7messages := govalidator.MapData{
 8    "name": []string{"required:用户名不能为空", "between:3到8位"},
 9    "age":  []string{"digits:手机号码为11位数字"},
10}
11
12opts := govalidator.Options{
13    Request:         ctx.Request, // request object
14    Rules:           rules,       // rules map
15    Messages:        messages,    // custom message map (Optional)
16    RequiredDefault: false,       // all the field to be pass the rules
17}
18v := govalidator.New(opts)
19e := v.Validate()
20
21//校验结果判断
22if len(e)>0 {
23    ctx.JSON(200, e)
24    return
25}

7、INI配置文件读取操作,可分别加载多个配置文件;

utils/config.go

代码语言:javascript
复制
1RootPath="/Users/baidu/data/golang/gopath/src/go-gin-mvc"
2var err error
3Config, err = ini.Load(RootPath+"/conf/config.ini");
4if err != nil {
5    fmt.Printf("Fail to read file: %v", err)
6    os.Exit(1)
7}

应用实例 models/orm.go

代码语言:javascript
复制
1//从库添加
2slaves := utils.Config.Section("mysql_slave").Keys()
3for _, s_dsn := range slaves {
4    _dbs, err := xorm.NewEngine("mysql", s_dsn.String())
5    ...
6}

8、定时任务;

main.go

代码语言:javascript
复制
1//定时程序启动
2c := cron.New()
3//数据库状态检查
4c.AddFunc("*/600 * * * * *", models.DbCheck)
5c.Start()

cmd/xorm安装注意事项

正常安装命令:

代码语言:javascript
复制
1go get github.com/go-xorm/cmd/xorm

但会报错,有两个包无法安装,

代码语言:javascript
复制
1cloud.google.com/go/civil
2golang.org/x/crypto/md4

移步到https://github.com/GoogleCloudPlatform/google-cloud-go下载相应的包 GOPATH目录下新建cloud.google.com 文件夹(与github.com同级)

代码语言:javascript
复制
1cloud.google.com/go/civil
2golang.org/x/crypto/md4

进入cmd/xorm 运行命令

代码语言:javascript
复制
1go build

查看帮助 xorm help reverse

xorm生成struct

代码语言:javascript
复制
1xorm reverse mysql "root:12345678@tcp(dbm1.baidu.com:3306)/test?charset=utf8" .

项目地址:https://github.com/mydevc/go-gin-mvc


版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 此项目集成了小型网站开发常用的功能:
  • 1、基于redis连接池存储的cache操作;
  • 2、基于redis连接池存储的session操作;
  • 注意这里的连接池是独立于cache操作redis的连接池,需单独配置参数。
  • 3、基于xorm的数据库操作,主从分离配置,支持多从库配置,鲜活连接定时PING操作,集成xorm/cmd;
  • 4、基于rabbitmq的队列应用,注意生产者与消费者队列名称的一致性
  • 多个任务可发送到一个队列,也可以灵活应用一个队列一个任务; 生产者与消费者消息传递的是序列化的结构体,结构体由生产者提供,并自行反序列化操作;
  • 5、csrf防跨站攻击
  • 6、数据验证,可自定义友好错误提示,更多实例参考;
  • 7、INI配置文件读取操作,可分别加载多个配置文件;
  • 8、定时任务;
  • cmd/xorm安装注意事项
  • 正常安装命令:
  • xorm生成struct
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档