社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
基于beego做一个mvc结构的测试工程,实现三个层的交互,其中model关联一个远程的mysql数据库,view层用来显示数据库中读取的部分内容.
我用的是mac系统 Mojave 10.14.3 (18D109)
https://golang.org
在这里下载安装,国内访问不了,需要翻墙, 如果不能翻墙,可以在别的地方找一下安装包,我安装的是 go1.11 darwin/amd64
https://desktop.github.com/
https://git-scm.com/download/mac
找自己喜欢的网站下载个安装包就可以,然后安装一个GIT环境,我的是git version 2.17.2 (Apple Git-113)
https://code.visualstudio.com/
下载一个最新的版本安装上就可以了,我用版本是 1.31.0 (1.31.0)
安装后将插件也一并安好,包括Rich go language support for vsc、Code Runner、Vim等等, 按自己的喜好来配置就好
安装之前首先要设置一下环境变量,我直接在 ~/.bash_profile 这个文件中修改,export GOPATH="/Users/xuanwenchao/go" 设置好后让确认环境变量生效,执行以下命令就可以开始安装了,bee也一并安装。
go get -u github.com/astaxie/beego
go get -u github.com/beego/bee
只需执行如下命令即可安装完成
go get -u github.com/go-sql-driver/mysql
终于安装好了环境,接下来需要在命令行下进入目录$GOPATH/src,使用如下使命令来创建测试工程结构:
bee new zazis
这时系统会出现
2019/02/13 14:39:57 INFO ▶ 0001 Creating application...
create /Users/xuanwenchao/go/src/zazis/ create /Users/xuanwenchao/go/src/zazis/conf/ create /Users/xuanwenchao/go/src/zazis/controllers/ create /Users/xuanwenchao/go/src/zazis/models/ create /Users/xuanwenchao/go/src/zazis/routers/ create /Users/xuanwenchao/go/src/zazis/tests/ create /Users/xuanwenchao/go/src/zazis/static/ create /Users/xuanwenchao/go/src/zazis/static/js/ create /Users/xuanwenchao/go/src/zazis/static/css/ create /Users/xuanwenchao/go/src/zazis/static/img/ create /Users/xuanwenchao/go/src/zazis/views/ create /Users/xuanwenchao/go/src/zazis/conf/app.conf create /Users/xuanwenchao/go/src/zazis/controllers/default.go create /Users/xuanwenchao/go/src/zazis/views/index.tpl create /Users/xuanwenchao/go/src/zazis/routers/router.go create /Users/xuanwenchao/go/src/zazis/tests/default_test.go create /Users/xuanwenchao/go/src/zazis/main.go 2019/02/13 14:39:57 SUCCESS ▶ 0002 New application successfully created! |
在连接mysql之前我们先需要配置数据库的相关连接信息,在工程的conf目录下,有一个app.conf文件,我们在这里面加上数据库的配置信息
接下来在models目录下新建一个文件命名为modelbase.go
因为配置文件也属于文件系统,因此我用这个model来读配置文件用,文件内容如下:
package models
import (
"github.com/astaxie/beego"
)
type modelbase struct {
MSQL_Hostname string
MSQL_Port string
MSQL_Username string
MSQL_Password string
}
func (m *modelbase) init() {
m.MSQL_Hostname = beego.AppConfig.String("dev::mysqlhost")
m.MSQL_Port = beego.AppConfig.String("dev::mysqlport")
m.MSQL_Username = beego.AppConfig.String("dev::mysqlusername")
m.MSQL_Password = beego.AppConfig.String("dev::mysqlpassword")
}
接下来创建一个数据库中某一个表的对应model文件,起名为userinfo_m.go, 该文件主要实现的功能包括, 定义一个与表结构一致的struct定义,初始化数据库连接配置,提供一个对外的接口用来获取指定区间的用户信息(只是测试用,所以比较简单),代码如下:
package models
import (
"fmt"
"log"
"time"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
type Flowuser struct {
Idd int64 `orm:"pk"` //指定主键
Phone string
Name string
Status int
Addtime time.Time
Balance int64
Password string
Logtime string
Infoidx int64
Signdates string
Deviceid string
Ip string
Qpass string
City string
}
func init() {
const dbName string = "flowtest" //数据库的名称
var model modelbase
model.init() //创建数据库连接信息
dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8", model.MSQL_Username, model.MSQL_Password, model.MSQL_Hostname, model.MSQL_Port, dbName)
orm.Debug = true //打开调试模式,可以看到请求信息
orm.RegisterDriver("mysql", orm.DRMySQL)//注册驱动引擎
orm.RegisterModel(new(Flowuser))//注册表对应的struct
err := orm.RegisterDataBase("default", "mysql", dbDSN)
if err != nil {
fmt.Printf("^^^^%v", err)
}
}
//返回值为实际读取到的记录数量和详细内容
func GetUserInfoList(offset int, limitCount int) (int64, []Flowuser) {
const tableName string = "flowuser"
if limitCount <= 0 {
return 0, nil
}
qb, err := orm.NewQueryBuilder("mysql")//通过ORM创建QueryBuilder对象
if err != nil {
log.Printf("NewQueryBuilder failed! err=%v", err)
return 0, nil
}
//根据传入的参数来查询指定范围的数据
qb.Select("*").From(tableName).Where("phone IS NOT NULL").Limit(limitCount).Offset(offset)
sql := qb.String()
var users []Flowuser//保存返回的结果记录
db := orm.NewOrm()//创建数据库对象
count, err := db.Raw(sql).QueryRows(&users)//执行sql
if err != nil {
log.Printf("QueryRows failed! err=%v", err)
return 0, nil
}
return count, users
}
从mysql读出来的数据我们直接显示在网页上,因为我们需要创建一个显示的模板,先在views目录下创建一个文件,命名为:userlist.tpl, 因为我不会CSS,HTML也学的不好,因此没有做任何好看的效果,直接用最简单的HTML中嵌套一个table来实现记录显示,代码如下:
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
<head/>
<body>
total count is <em>{{.Count}}</em> <br><br>
<table border="1">
<tr>
<th>Idd</th>
<th>Phone</th>
<th>Balance</th>
<th>Deviceid</th>
<th>Logtime</th>
<th>City</th>
<th>Status</th>
<th>Addtime</th>
<th>Signdates</th>
<th>Ip</th>
</tr>
{{range .Users}}
<tr>
<td>{{.Idd}}</td>
<td>{{.Phone}}</td>
<td>{{.Balance}}</td>
<td>{{.Deviceid}}</td>
<td>{{.Logtime}}</td>
<td>{{.City}}</td>
<td>{{.Status}}</td>
<td>{{.Addtime}}</td>
<td>{{.Signdates}}</td>
<td>{{.Ip}}</td>
</tr>
{{end}}
</table>
</body>
</html>
这里面用到的变量名, 将会在controller中传值过来.
同样先在我们的目录结构中找到controllers目录,然后新创建一个文件命名为:testmodel.go, 然后我们在coltroller中的工作就是使用model获得数据再使用view将数据展示给前端的页面,因为我的测试环境数据也有几千万用户,因此我们可以跳过前1万条记录,然后读取20条,实现代码如下:
package controllers
import (
"fmt"
"zazis/models"
"github.com/astaxie/beego"
)
type TestModelController struct {
beego.Controller
}
func (c *TestModelController) Get() {
//跳过前1万条数据后,取20条用户数据
counts, users := models.GetUserInfoList(10000, 20)
c.Data["Title"] = "test mySQL"
c.Data["Count"] = counts //结果数据传递给view
c.Data["Users"] = users //结果数据传递给view
c.TplName = "userlist.tpl" //指定用哪个view来显示
}
controller代码写好后,我们需要给他加一个入口, 用来在浏览器中可以找到他的,打开工程目录下的routers文件夹,点击router.go文件,在init函数中新加一个入口testmodel来调用我们的controller,如下图所示:
代码都写好后, 接下来回到命令行下,对应的工程目录下执行命令:bee run (也可以在VSC中执行),这时可以看到命令行提示,已经在本机的端口开始监听等待连接了:
这时就可以打开本机的浏览器输入http://localhost:8080/来看结果了,会显示如下界面:
这个界面说明我们的服务器运营正常, 接下来,修改网址为:http://localhost:8080/testmodel 显示的结果如下:
关于下面这个问题,网上说法很多, 各种奇怪的方式都改好了,我也分享一下我的看法, 当然未必对所有人都是对的,但仍然希望对你有所帮助.
must have one register DataBase alias named default
这个问题,我发现有两种情况下会出现,第一个是如果你的数据库的名称中没一个叫default(或别名)的的话,在注册数据库时仍然可以这样写:
err := orm.RegisterDataBase("default", "mysql", dbDSN)
也就是说这里可以写成死的,也没有关系,不然可能会出这个错误。
第二个原因我个人这里出现最多的是因为非本地数据库,有时连接会因网络问题导致失败时,可能也会报出这个错误.比如我随意改一个错误的IP或密码,当然初始化时他首先会报出:
[ORM]2019/02/13 16:03:20 register db Ping `default`, Error 1045:
此时如果你继续执行创建db对象的语句时,他还是会报出这种错误;
db := orm.NewOrm()
结果就会是这样:
must have one register DataBase alias named `default`
总结的来说,用户名密码或IP错语,是可以提前发现的, 但如果是网络问题,或能也同样报这种错语, 就容易识解.(个人记录用)
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!