go(五)
1、gorilla/mux
导入:
import "/gorilla/mux"
gorilla/mux是一个强大的路由,小巧但是稳定高效,不仅可以支持正则路由还可以按照Method,header,host等信息匹配
使用示例:
r := mux.NewRouter()
//与http.ServerMux不同的是mux.Router是完全的正则匹配,设置路由路径/index/,如果访问路径/idenx/hello会返回404
//设置路由路径为/index/访问路径/index也是会报404的,需要设置r.StrictSlash(true), /index/与/index才能匹配
r.HandleFunc("/index/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("root path"))
})
//mux.Vars(r)会返回该请求所解析出的所有参数(map[string]string)
//访问/hello/ghbai 会输出 hello ghbai
r.HandleFunc("/hello/{name:[a-zA-Z]+}", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(fmt.Sprintf("hello %s", mux.Vars(r)["name"])))
})
http.Handle("/", r)
在我接触的项目中,有这样的应用:
func (registry *MsgRegistry) RegisterHandlers(r *mux.Router) {
registerHandlers(r)
}
//其中registerHandlers方法为:
func registerHandlers(r *mux.Router) {
glog.V(2).Info("register handlers")
registerHttpHandlers(r)
registerUserHandlers()
}
//在打开服务的时候调用了:
func (s *GameServer) StartServer(dispatcher MsgDispatcher) {
s.dispatcher = dispatcher
r := mux.NewRouter()
http.Handle("/", r)
s.dispatcher.RegisterHandlers(r)
glog.Fatal(http.ListenAndServe(fmt.Sprintf("%v", bindHost), nil))
}
2、golang/glog
导入:
import "/golang/glog"
glog是著名的google开源C++日志库glog的golang版本,glog是一个轻量级的日志库,上手简单不需要配置文件并且稳定高效,但是可以自定义控制的内容就少了。 glog主要有以下几个特点:
glog有四种日志等级INFO < WARING < ERROR < FATAL,不同等级的日志是打印到不同文件的,低等级的日志文件中(INFO)会包含高等级的日志信息(ERROR)
通过命令行传递参数 –log_dir指定日志文件的存放目录,默认为os.TempDir()
可以根据文件大小切割日志文件,但是不能根据日期切割日志文件
日志输出格式是固定的(Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg…)不可以自定义
在程序开始时需要调用flag.Parse()解析命令行参数,在程序退出时需要调用glog.Flush() 确保将缓存区中的内容输出到文件中。
使用示例:
func main() {
//初始化命令行参数
flag.Parse()
//退出时调用,确保日志写入文件中
defer glog.Flush()
glog.Info("hello, glog")
glog.Warning("warning glog")
glog.Error("error glog")
glog.Infof("info %d", 1)
glog.Warningf("warning %d", 2)
glog.Errorf("error %d", 3)
}
3、bson
示例:
package main
import (
"fmt"
"/v2/mgo/bson"
)
type TestStruct struct {
Name string
ID int32
}
func main() {
fmt.Println("start")
data, err := bson.Marshal(&TestStruct{Name: "Bob"})
if err != nil {
panic(err)
}
fmt.Println("%q", data)
value := TestStruct{}
err2 := bson.Unmarshal(data, &value)
if err2 != nil {
panic(err)
}
fmt.Println("value:", value)
mmap := bson.M{}
err3 := bson.Unmarshal(data, mmap)
if err3 != nil {
panic(err)
}
fmt.Println("mmap:", mmap)
}
4、mgo
导入包:
import "gopkg.in/mgo.v2"
mgo这个包是go语言与mongodb交互的包。
连接mongodb:
session, err := mgo.Dial(url)
使用某个集合
c := session.DB(database).C(collection)
常用方法:
4.1、查找
type GameLog struct {
RoomId int `bson:"roomId"`
Status int `bson:"status"`
GameInfo UserGameInfoDB `bson:"gameInfo"`
DismissInfo DismissInfoDB `bson:"dismissInfo"`
CreateTime int64 `bson:"createTime"`
}
items := &GameLog{}
c.Find(bson.M{"roomId": roomId}).One(items)
//查找roomId字段为roomId(一个变量)的结果,输出到以GameLog格式的items变量中
4.2、更新并返回最新值
const (
userIdC = "user_id_index"
)
ch := mgo.Change{
Update: bson.M{"$inc": bson.M{"seq": 1}},
ReturnNew: true,
}
next := &sequence{}
err := util.WithUserCollection(userIdC, func(c *mgo.Collection) error {
_, err := c.Find(bson.M{"name": "index"}).Apply(ch, &next)
//err : not found
return err
})
//对user_id_index集合的seq字段加一,并返回最新值,seq为自增字段
4.3、插入数据
_, err := c.Upsert(bson.M{"userName": u.UserName}, u)
其中bson.M( Key : Value )的使用需要导入“gopkg.in/mgo.v2/bson”包。用于go的结构与Mongodb的集合进行转换。
注意事项
如果go需要连接到mongodb的多个数据库中,且多个数据库都有单独的认证用户,则需要单独写连接语句。
flag.StringVar(&dbUrl, "dburl", "mongodb://zhangliao:zhangLiao2018@127.0.0.1/poker_user", "db url.")
flag.StringVar(&dbgamedataUrl, "gamedataurl", "mongodb://zhangliao:zhangLiao2018@127.0.0.1/gamedata", "gamedata url.")
flag.StringVar(&logDbUrl, "logurl", "mongodb://zhangliao:zhangLiao2018@127.0.0.1/poker_log", "log url.")
func getSession() *mgo.Session {
if mgoSession == nil {
var err error
mgoSession, err = mgo.Dial(dbUrl)
if err != nil {
panic(err)
}
mgoSession.SetPoolLimit(dbPoolLimit)
}
return mgoSession.Clone()
}
func getLogSession() *mgo.Session {
if logSession == nil {
var err error
logSession, err = mgo.Dial(logDbUrl)
if err != nil {
panic(err)
}
logSession.SetPoolLimit(dbPoolLimit)
}
return logSession.Clone()
}
func getJavaSession() *mgo.Session {
if gamadataSession == nil {
var err error
gamadataSession, err = mgo.Dial(dbgamedataUrl)
if err != nil {
panic(err)
}
gamadataSession.SetPoolLimit(dbPoolLimit)
}
return gamadataSession.Clone()
}
否则会报没有权限执行相关命令的错误。
5、mysql
导入:
import _ "/go-sql-driver/mysql"
import "database/sql"
mysql包是go与mysql类数据库(mysql,mariadb等)交互的数据库驱动包
连接示例
db, err := sql.Open("mysql", "zhangliao:zhangLiao2018@tcp(127.0.0.1:3306)/gamelog?parseTime=true")
if err != nil{
log.Fatal(err)
}
defer db.Close()
然后对db操作即可。