1. 前言
本文中研究学习beego对于数据库的增删查改。beego的官方ORM DEMO不是很好,demo无法跑通,也无法自动创建表结构。因此,本文重新设计了学习流程。
参考文档:
2. 环境准备
1、安装ORM
go get github.com/astaxie/beego/orm
2、安装驱动
1 2 3
| go get -u github.com/mattn/go-sqlite3 go get -u github.com/go-sql-driver/mysql go get -u github.com/lib/pq
|
3. First Model
本节中创建一个名为User的Model,只有三个字段,Id、Name和Age。运行代码,创建sqlite数据库和user表结构,并且向user表中插入一条数据。
1、在vkbeego/models目录中创建main.go文件,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package main
import ( "fmt" "github.com/astaxie/beego/orm" _ "vkbeego/routers" _ "github.com/mattn/go-sqlite3" )
type User struct { Id int Name string Age int }
func create_table(){ name := "default"
force := true
verbose := true
err := orm.RunSyncdb(name, force, verbose) if err != nil { fmt.Println(err) } }
func init() { orm.RegisterDriver("sqlite3", orm.DRSqlite) orm.RegisterDataBase("default", "sqlite3", "db.sqlite3") orm.RegisterModel(new(User)) create_table() }
func main() { o := orm.NewOrm() o.Using("default")
user := new(User) user.Name = "Hankin"
fmt.Println(o.Insert(user))
}
|
2、运行代码
在models目录,go run main.go
,控制台输出创建表的信息。
3、查看执行效果
查看vkbeego/models目录,发现出现了db.sqlite3文件。如果运行代码时右键run,那么db.sqlite3文件会出现在根目录下。
使用navicat for sqlite,打开db.sqlite3数据库,可以看到创建的表和数据。
4. 增加数据
以上,已经实现了向数据库中添加数据,但是,Model的定义和注册、数据库的连接、插入数据的逻辑都在同一个文件中,非常混乱。因此需要对代码进行拆分,调整结构。
1、删除First Model
删除models目录下的main.go和db.sqlite3。
2、在models目录下新建models.go,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package models
import ( "fmt" "github.com/astaxie/beego/orm" _ "github.com/mattn/go-sqlite3" )
type User struct { Id int Username string Password string }
func create_table(){ name := "default"
force := false
verbose := true
err := orm.RunSyncdb(name, force, verbose) if err != nil { fmt.Println(err) } }
func init() { orm.RegisterModel(new(User)) orm.RegisterDriver("sqlite3", orm.DRSqlite) orm.RegisterDataBase("default", "sqlite3", "db.sqlite3") create_table() }
|
3、在routers/user.go中添加路由:
1
| beego.Router("/user/add", &user.AddController{})
|
4、在controllers/user目录中新建文件add.go,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package user
import ( "fmt" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" "vkbeego/models" )
type AddController struct { beego.Controller }
func (c *AddController) Get() { var username = c.GetString("username") fmt.Println(username) c.Ctx.WriteString("Please add user by post request.") }
func (c *AddController) Post() { var username = c.GetString("username") var password = c.GetString("password") var o = orm.NewOrm() o.Using("default") var user = new(models.User) user.Username = username user.Password = password o.Insert(user) c.Ctx.WriteString("add user: " + username)
}
|
5、测试
启动beego,使用Postman,发送Post请求到 http://localhost:8080/user/add ,请求参数包括username和password,成功写入参数到数据库。
5. 查看数据
1、在routers/user.go中添加路由:
1
| beego.Router("/user/list", &user.ListController{})
|
2、在controllers/user目录中新建文件list.go,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package user
import ( "fmt" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" "vkbeego/models" )
type ListController struct { beego.Controller }
func (c *ListController) Get() { var o = orm.NewOrm() o.Using("default") var qs orm.QuerySeter qs = o.QueryTable("user") var users []*models.User num, err := qs.All(&users,"Id", "Username") fmt.Printf("Returned Rows Num: %d, %s \n", num, err) fmt.Println(users[0].Username) c.Data["users"] = users c.TplName = "user/list.tpl" }
|
3、在views/user目录中新建list.tpl文件,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>User List</title> </head> <body> <h2>User List</h2> {{range .users}} <p> ID为:{{.Id}},用户名为:{{.Username}} </p> {{end}}
{{range $index,$user := .users}} <p> Index为:{{$index}},ID为:{{$user.Id}},用户名为:{{$user.Username}} </p> {{end}}
</body> </html>
|
4、测试
启动beego,使用Postman,发送Get请求到 http://localhost:8080/user/list ,即可看到用户列表。
6. 修改数据
1、在routers/user.go中添加路由:
1
| beego.Router("/user/update", &user.UpdateController{})
|
2、在controllers/user目录中新建文件update.go,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package user
import ( "fmt" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" "vkbeego/models" )
type UpdateController struct { beego.Controller }
func (c *UpdateController) Get() { c.Ctx.WriteString("Please use post request.") }
func (c *UpdateController) Post() { //id,_ := c.GetInt("id") username := c.GetString("username") password := c.GetString("password") new_password := c.GetString("new_password")
var o = orm.NewOrm() o.Using("default")
exist := o.QueryTable("user").Filter("UserName", username).Exist() if !exist{ c.Ctx.WriteString("Username doesn't exist!") return; }
var user models.User o.QueryTable("user").Filter("Username",username).Filter("Password",password).One(&user)
if o.Read(&user) == nil { user.Password = new_password if num, err := o.Update(&user); err == nil { fmt.Println(num) } }else { c.Ctx.WriteString("Username or password is wrong!") return; }
c.Ctx.WriteString("Password has been updated!") }
|
3、测试
启动beego,使用Postman,发送Post请求到 http://localhost:8080/user/update 进行密码的更新,请求参数包括username、password和new_password。
7. 删除数据
1、在routers/user.go中添加路由:
1
| beego.Router("/user/del", &user.DelController{})
|
2、在controllers/user目录中新建文件del.go,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package user
import ( "fmt" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" )
type DelController struct { beego.Controller }
func (c *DelController) Get() { c.Ctx.WriteString("Please use post request.") }
func (c *DelController) Post() { id,_ := c.GetInt("id")
var o = orm.NewOrm() o.Using("default")
num,err := o.QueryTable("user").Filter("Id",id).Delete() fmt.Printf("Returned Rows Num: %d, %s \n", num, err) if num != 0 { c.Ctx.WriteString("User has been deleted!") }else{ c.Ctx.WriteString("User Id doesn't exist! Can't delete!") } }
|
3、测试
启动beego,使用Postman,发送Post请求到 http://localhost:8080/user/del 进行删除数据,请求参数为id。
8. 结构体和表
上面的代码中,我们并没有指定结构体和数据库表的对应关系,那么它们是怎样关联起来的呢?
参考beego框架之orm模块——mysql、BeegoOrm 映射自定义表名以及自定义字段,可知在beego的models模块里,会自动处理结构体和数据库表的对应关系,比如:
1 2 3 4 5
| type User struct{ // 默认情况对应数据库的表名为:user MyName string // 默认情况对应数据库里user表字段为:my_name MyAge string // 默认情况对应数据库里user表字段为:my_age } orm.RegisterModel(new(User))
|
新的需求:
结构体名为User对应数据库的表名为test_user
MyName的成员对应数据库的字段名为MyName
MyAge的成员对应数据库的字段名为MyAge
那么该User的结构体又该如何定义呢?新需求的User结构体:
1 2 3 4 5 6 7 8 9 10
| type User struct{ MyName string `orm:"column(MyName)"` MyAge string `orm:"column(MySex)"` } orm.RegisterModel(new(User))
func (u *User) TableName() string { return "test_user" }
|
9. 后记
至此,beego的增删查改操作基本都已经涉及,更高级的查询在使用时再去学习。
源码分享:v0.0.1