内容简介:继续上节的代码。上节的代码是把数据存到了数组中。相当于存到了内存中了。现在操作MySQL。添加数据到mysql中,从mysql中查询数据,并删除一个类库的使用似乎没有什么太难的。test库yan_user表。
mysql
继续上节的代码。上节的代码是把数据存到了数组中。相当于存到了内存中了。现在操作MySQL。添加数据到 mysql 中,从mysql中查询数据,并删除
一个类库的使用似乎没有什么太难的。
test库yan_user表。
CREATE TABLE `yan_user` ( `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
操作库用这个 https://github.com/go-sql-driver/mysql 。go get -u github.com/go-sql-driver/mysql。
把添加的名字落入数据库。
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test") defer db.Close() if err != nil { panic(err) } stmt, err := db.Prepare("INSERT INTO yan_user SET name=?") if err != nil { panic(err) } res, err := stmt.Exec(name) if err != nil { panic(err) } id, err := res.LastInsertId() if err != nil { panic(err) }
查询的那块也从mysql中查询。
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test") defer db.Close() if err != nil { panic(err) } rows, err := db.Query("SELECt * FROM yan_user") if err != nil { panic(err) } var nameList []map[string]interface{} for rows.Next() { var id int var name string err = rows.Scan(&id, &name) if err != nil { panic(err) } nameList = append(nameList, map[string]interface{}{"id": id, "name": name}) }
redis
类库使用的是 https://github.com/go-redis/redis 。
go get -u github.com/go-redis/redis
在添加名字,名字入库的时候,把id 跟name存入list中。
// 插入到 redis 中 client := redis.NewClient(&redis.Options{ Addr: "x.x.x.x:18000", Password: "", // no password set DB: 0, // use default DB }) pong, err := client.Ping().Result() fmt.Println(pong, err) jsonRes, err := json.Marshal(map[string]interface{}{"id": id, "name": name}) if err != nil { panic(err) } client.LPush("name_list", jsonRes)
然后再写一个接口是从redis查出来的数据。
http.HandleFunc("/search_from_redis", func(w http.ResponseWriter, r *http.Request) { // 插入到redis中 client := redis.NewClient(&redis.Options{ Addr: "x0.x0.xx.15:18000", Password: "", // no password set DB: 0, // use default DB }) pong, err := client.Ping().Result() fmt.Println(pong, err) res, err := client.LRange(nameListKey, 0, 100).Result() if err != nil { panic(err) } type Name struct { Id int `json:"id"` Name string `json:"name"` } var name Name var nameList []Name for _, value := range res { json.Unmarshal([]byte(value), &name) nameList = append(nameList, name) } data := map[string]interface{}{"name_list": nameList} list, err := json.Marshal(data) if err != nil { fmt.Println("json.Marshal failed:", err) return } w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, string(list)) //这个写入到w的是输出到客户端的 })
界面如下
image.png
包管理工具
上面我们go get了mysql 跟redis 的库。这个库放到了我配置的第一个gopath下面了。
vendor目录。
现在我在代码中import里面引入一个随便写的类库 github.com\go-d
。编辑器就会告诉你没有在gopath中找到。如果在src下面创建了一个vendor目录,报错信息的第一条就是vendor下面没有这个库。
vendor是1.5版本后加的。查找依赖包的解决方案如下(摘自极客时间):
1.当前包下的vendor目录
2.向上级目录查找,直到找到src下的vendor 目录
3.在GOPATH下面查找依赖包
4.在GOROOT目录下查找
但你看控制台从报错信息中就能看出规律。如下是我的:
cannot find package "github.com/go-d" in any of: F:\iProject\xiaotianquan\src\vendor\github.com\go-d (vendor tree) C:\Go\src\github.com\go-d (from $GOROOT) F:\iProject\gopath\src\github.com\go-d (from $GOPATH) F:\iProject\xiaotianquan\src\github.com\go-d
依赖管理的 工具 有好几个。文末参考资料中自行了解。
glide
安装方式去 官方文档 。
windows的话,因为我安装过 gitbash
,所以在gitbash中执行 curl https://glide.sh/get | sh
也就安装好了(安装到了go/bin目录下了)。(但我的版本有问题,下面会说到。不得不去github上找低版本的 https://github.com/Masterminds/glide/releases )
我在之前的代码中又拷贝了一份目录(web3)。在main.go(我demo的文件)同级目录下。我执行glide init ,看到了glide.yaml文件,文件的内容。
package: web3 import: - package: github.com/go-redis/redis version: v6.15.2 - package: github.com/go-sql-driver/mysql version: v1.4.1
是不是有种composer的感觉。
执行glide ,会在我web3(web3在src目录下)的目录下生成一个vendor目录(而不是在src)。那么下次引入其他的类库会在这个vendor里面找。
但使用的过程中报错了。我找到了一条issue https://github.com/Masterminds/glide/issues/873
。应该该版本在windows下的问题。我安装的版本是glide version v0.13.2。有人说这个版本0.12.3有效。
Unable to export dependencies to vendor directory: Error moving files: exit status 1. output: Access is denied. 0 dir(s) moved.
0.12.3 确实可以。我把下载glide 放到了go/bin下面替换了之前安装的版本。
然后执行glide install。vendor目录下就有了相关的类库了。这样以后依赖管理就方便了。我的包也不用去都放到一个gopath下了(甚至就放到我的项目目录下的vendor里面)。
更多使用glide版本管理的方式。请看官网: https://glide.readthedocs.io
beego框架略览
到现在细数下做到的功能。
1.模板渲染
2.mysql操作
3.redis操作
4.json操作
5.版本管理(glide)
OK,到现在我们已经具备了CURD的能力(虽然我没有写D跟U的代码)。来看一个框架beego。有人说这是 go 的ThinkPHP。
安装bee工具。go get github.com/beego/bee。
我拷贝一个文件夹起名为web4。进入其目录。创建一个项目 bee new myproject
cd myproject,执行 bee run。提示我 main.go:5:2: cannot find package "github.com/astaxie/beego
。OK,没关系。我开始安装下beego。这次就用glide去管理吧。
在myproject 执行glide init。然后glide install。
OK,bee run执行(由于我本地装了Jenkins,我需要到conf/app.conf改成其他端口,比如8081吧)
OK,http://127.0.0.1:8081/ 你看到了 Welcome to Beego
。
beego 版 名单
controllers下面我们新建一个name.go。我就把整个代码贴下去了哈。
package controllers import ( "encoding/json" "fmt" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" "github.com/gomodule/redigo/redis" ) type NameController struct { beego.Controller } func (c *NameController) Get() { c.Data["Website"] = "beego.me" c.Data["Email"] = "astaxie@gmail.com" c.TplName = "name/index.tpl" } func (c *NameController) Add() { name := c.Input().Get("name") o := orm.NewOrm() r := o.Raw("INSERT INTO yan_user SET name=?", name) res, err := r.Exec() if err != nil { panic(err) } id, err := res.LastInsertId() if err != nil { panic(err) } c.Data["json"] = &id conn, err := redis.Dial("tcp", "xx.x0.x.x5:18000") if err != nil { panic(err) } defer conn.Close() jsonRes, err := json.Marshal(map[string]interface{}{"id": id, "name": name}) if err != nil { panic(err) } conn.Do("lpush", "name_list", jsonRes) c.ServeJSON() } func (c *NameController) Search() { type Name struct { Id int `json:"id"` Name string `json:"name"` } var nameList []Name o := orm.NewOrm() num, err := o.Raw("SELECT * FROM yan_user").QueryRows(&nameList) if err != nil { panic(err) } fmt.Println("user nums: ", num) data := map[string][]Name{"name_list": nameList} c.Data["json"] = &data c.ServeJSON() } func (c *NameController) SearchFromRedis() { conn, err := redis.Dial("tcp", "xx.xx.x.xx:18000") if err != nil { panic(err) } defer conn.Close() res, err := redis.Values(conn.Do("lrange", "name_list",0 ,100)) if err != nil { panic(err) } type Name struct { Id int `json:"id"` Name string `json:"name"` } var name Name var nameList []Name for _, value := range res { json.Unmarshal(value.([]byte), &name) nameList = append(nameList, name) } data := map[string]interface{}{"name_list": nameList} if err != nil { fmt.Println("json.Marshal failed:", err) return } c.Data["json"] = &data c.ServeJSON() }
配置路由
beego.Router("/", &controllers.MainController{}) beego.Router("/name/index", &controllers.NameController{}) beego.Router("/name/add", &controllers.NameController{},"post:Add") beego.Router("/name/search", &controllers.NameController{},"post:Search") beego.Router("/name/search_from_redis", &controllers.NameController{},"post:SearchFromRedis")
初始化的一些配置。在入口main.go,需要做下面的事情。
- 指定数据库 (一定别忘了指定数据库驱动github.com/go-sql-driver/mysql,不引入会报
register db
default, sql: unknown driver "mysql" (forgotten import?)
) - 模板解析的左右标签改下(因为会跟vue冲突)
package main import ( _ "web4/myproject/routers" "github.com/astaxie/beego" _ "github.com/go-sql-driver/mysql" "github.com/astaxie/beego/orm" ) func init() { orm.RegisterDriver("mysql", orm.DRMySQL) orm.RegisterDataBase("default", "mysql", "root:root@/test?charset=utf8") } func main() { beego.BConfig.WebConfig.TemplateLeft = "<<<" beego.BConfig.WebConfig.TemplateLeft = ">>>" beego.Run() }
文档中redis 缓存
使用缓存别忘下载对应的文件。
glide get github.com/astaxie/beego/cache glide get github.com/gomodule/redigo/redis
用法,头部先引入
"github.com/astaxie/beego/cache" _ "github.com/astaxie/beego/cache/redis"
bm, err := cache.NewCache("redis", `{"conn":"xx.x.x.x:18000"}`) if err != nil { panic(err) } timeoutDuration := 100 * time.Second // 当然这里还需要引入time包。 err = bm.Put("aaaa", "2222", timeoutDuration)
看下配置
{"key":"collectionName","conn":":6039","dbNum":"0","password":"thePassWord"}
文档中说是 key: Redis collection 的名称
。没搞明白是啥意思。追了下代码,看明白了。这个key就是前缀。比如你想在代码中Put("name","xiaoming", 100 * time.Second),实际上key如果你不指定默认就是 beecacheRedis:name
。如果你指定了就是key:name。如果指定的key为空字符串。那么就是:name(不会因为你填的空白字符串,而把冒号去掉。)。所以当你纠结在中断找不get的不到的时候,别忘了前缀哈。
key的拼接在 ./github.com/astaxie/beego/cache/redis/redis.go
中。如下:
func (rc *Cache) associate(originKey interface{}) string { return fmt.Sprintf("%s:%s", rc.key, originKey) }
由于Cache 封装的方法太少。我想用redis list 的功能,只能直接用redigo方法了(代码参考上面的name.go代码)。
总结
这里没有提及到orm的使用。实际上,参考文档就会马上完成用orm的方式。
参考资料:
- 《build-web-application-with-golang》 https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/preface.md
*《Go database/sql tutorial》 http://go-database-sql.org/index.html - 《go依赖包管理工具对比》 https://ieevee.com/tech/2017/07/10/go-import.html
- 《包管理工具 glide》 https://learnku.com/articles/23503/package-management-tool-glide
- 《Go语言从入门到实战》极客时间,蔡超,22节依赖管理
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 赵童鞋带你入门PHP(六) ThinkPHP框架入门
- Cucumber框架入门篇
- Koa框架基础快速入门
- 框架 | FastDFS 入门到应用
- Authlib强大OAuth框架入门
- Ginkgo测试框架入门(golang)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。