Go语言实战 - revel框架教程之MongDB的最佳搭档revmgo
由于revel框架本身对于model层的编写没有提供任何指导,所以在设计这部分的时候就有些犹豫,反复斟酌到底怎样才算是最佳实践。
我在做山坡网的时候刚开始也纠结了一下,拿不准mongodb的session的创建和销毁应该在什么地方处理。直到有一天看到了revmgo的作者在与revel的作者讨论(具体内容在这里),就去研究了下revmgo,之后立即就用它替换了我自己的实现。
先说下用法吧。
1. 在app.conf添加mongodb的连接字符串。
revmgo.dial = mongodb://username:password@serverip/database
2. 在controller层的init方法中初始化。
func init() {
revmgo.ControllerInit()revel.OnAppStart(func() {
revmgo.AppInit()
}
}
3. 把MongoController签入到所有需要访问数据库的Controller中。
type Application struct {
*revel.Controller
revmgo.MongoController
}
这里有个小插曲,revmgo.MongoController已经内嵌过revel.Controller了,但此处还是不能省略*revel.Controller。原因是revel在确定有效的controller的action的时候只反射了一层,跟revel的作者讨论过这个问题,后来他说服我了,原因是如果不断递归反射的话复杂度会变高而且性能损失会不可控。好吧,其实这也算是OO的遗毒。看起来挺难受,多写了一行代码,设计上也不太舒服,但仔细想来对性能和整体的复杂度却都有好处,既然如此,何必执着设计上的完美呢?简单就是美。
4. 修改Dal的实现。
//Data access layer
type Dal struct {
session *mgo.Session
}//创建新的Dal
func NewDal(session *mgo.Session) *Dal {
if session == nil {
panic("session cannot be nil.")
}
return &Dal{session}
}
现在来看看在controller中如何使用。
func (c *Account) HandleRegister(user *models.MockUser) revel.Result {
//Validate parameter here.
dal := models.NewDal(c.MongoSession)
err := dal.RegisterUser(user)
//Biz logic here
}
revmgo的内部实现非常简单,整个代码也就110行,基本可以一目了然。
总的来说,调用revmgo.AppInit()的时候读取app.conf中的配置,可以看到有两个配置项有效,"revmgo.dial"为连接字符串,"db.spec"确定mongodb的session的重复利用方式(具体含义参考这里),然后建立session。
之后的revmgo.ControllerInit注册了两个interceptfunc,用于在controller的action访问前后建立和关闭session。
func ControllerInit() {
revel.InterceptMethod((*MongoController).Begin, revel.BEFORE)
revel.InterceptMethod((*MongoController).End, revel.FINALLY)
}
其实我对于这个设计颇有微词,ControllerInit的存在简直就是对revel的module设计机制的嘲笑,很难相信作为一个模块竟然还需要使用者手动调用初始化函数。这个部分应该不难处理,常规来说只应该让使用者注册需要使用的module和执行顺序,初始化和解构都由module管理器负责。跟revel的作者也讨论了这个问题,看他似乎有别的设计意图,等等看revel 1.0正式发布时会是什么样子吧。
Go语言实战 - revel框架教程之MongDB的最佳搭档revmgo的更多相关文章
- Go语言实战 - revel框架教程之CSRF(跨站请求伪造)保护
CSRF是什么?请看这篇博文“浅谈CSRF攻击方式”,说的非常清楚. 现在做网站敢不防CSRF的我猜只有两种情况,一是没什么人访问,二是局域网应用.山坡网之前属于第一种情况,哈哈,所以至今没什么问题. ...
- revel框架教程之CSRF(跨站请求伪造)保护
revel框架教程之CSRF(跨站请求伪造)保护 CSRF是什么?请看这篇博文“浅谈CSRF攻击方式”,说的非常清楚. 现在做网站敢不防CSRF的我猜只有两种情况,一是没什么人访问,二是局域网应用.山 ...
- Go语言实战 - revel框架教程之权限控制
一个站点上面最基本都会有三种用户角色,未登录用户.已登录用户和管理员.这一次我们就来看看在revel框架下如何进行权限控制. 因为revel是MVC结构的,每一个url其实都会映射到一个具体的Cont ...
- Go语言实战 - revel框架教程之用户注册
用户注册.登录和注销是任何一个网站都必然会有的功能,可以说,这是重新造轮子做多的领域,每个做网站的人应该都做过很多遍.见微知著,从这么一个小功能其实就可以看到所使用的web框架中的大部分东西. 今天就 ...
- Go语言实战 - revel框架教程之缓存和Job
所有的网站应该都会有一个非常简单的需求,首页一秒之内打开. 满足的方式主要有两种: 页面静态化,效果最好,对服务器基本没负担,只要带宽足够就好了.我知道一个PV过亿的站点就是全站静态(以前新浪也是), ...
- revel框架教程之缓存和Job
Go语言实战 - revel框架教程之缓存和Job 所有的网站应该都会有一个非常简单的需求,首页一秒之内打开. 满足的方式主要有两种: 页面静态化,效果最好,对服务器基本没负担,只要带宽足够就好了 ...
- revel框架教程之权限控制
Go语言实战 - revel框架教程之权限控制 一个站点上面最基本都会有三种用户角色,未登录用户.已登录用户和管理员.这一次我们就来看看在revel框架下如何进行权限控制. 因为revel是MVC结构 ...
- HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID
HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID HealthKit开发准备工作 在开发一款HealthKit应用程序时,首先需要讲解HealthKit中有哪些类,在i ...
- Swift2.0语言教程之Swift2.0语言中的标准函数
Swift2.0语言教程之Swift2.0语言中的标准函数 Swift2.0中的标准函数 函数除了可以根据参数列表的有无分为无参函数和有参函数,还可以从定义角度分为用户自定义函数和标准函数两种.以上的 ...
随机推荐
- Drools 查询学习
Drools 查询学习查询以 query 关键字开始,以 end 关键字结束,在 package 当中一个查询要有唯一的名称,查询的内容就是查询的条件部分,条件部分内容的写法与规则的 LHS 部分写法 ...
- Json格式示意图
json视图工具:http://www.bejson.com/jsonviewernew/ 一.Json格式化,(看到数组里面又有数组一下子疑问不是合格json):尾门地址查询: =>=> ...
- 【NuGet】搭建自己团队或公司的NuGet
昨天接到领导安排,要搭建自己的NuGet,归结原因是自己前段时间在NuGet中安装mongoDb driver时,发现访问不了,无奈领导找的运维解决,也是此次任务的“导火索”……,好了,还是干活吧. ...
- java中的单例模式(懒汉式+饿汉式)
什么是单例模式: 单例模式既只能在自己本类中创建有且唯一的一个实例(姑且不考虑映射的情况)通过方法将该实例对外公开 第一种:单例模式-懒汉式 既调用getInstance()方法返回实例之前判断有没有 ...
- js中的日期控件My97 DatePicker---那些打酱油的日子
使用WdatePicker插件来渲染日期类型的页面. 以下代码用到的属性有: isShowClear是否显示清空按钮 skin皮肤的样式 readOnly是否只读 maxDate:最大的选择时间 &l ...
- 记录同事的一个bug-ajax-413错误-fullhead
症状表现为在form下面的textarea里的字符数只有几十个的时候,请求可以成功,但是如果有几百字,则会出现413错误,提示fullhead,我第一反应是cookie体积太小,但是清了缓存还是一样的 ...
- 530 User cannot log in, home directory inaccessible.
服务器是winserver,控制面板-用户账号里新建了一个Ftp账户用来做ftp连接.可在本地连接FTP总提示530 User cannot log in, home directory inacce ...
- MariaDB 双主复制的配置
环境 Master1/Master2 系统 IP 数据库版本 Master1 CentOS6.7 10.10.3.211 mariadb-10. ...
- 两种让tableview返回顶部的方法
1. [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_currentRow inSection:0] animat ...
- 简单C#、asp.net mvc验证码的实现
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;u ...