pop 的基础使用。
pop 是 gobuffalo 默认的 orm 包,当然也可以在其他项目使用 pop。但是 pop 官方强调自己不是 orm,只是具备 orm 的功能。其主要的优点就是:
- 支持 CRUD 操作
- 代码定义模型
- 用于创建,删除和修改的迁移工具
- 数据库支持:PostgreSQL,MySQL,SQLite
- ActiveRecord UUID 模式
- YAML 配置
- 易于环境变量使用
- 创建和更新每条记录的时间戳
- 支持事务
安装#
$ go get github.com/gobuffalo/pop/...
$ go install github.com/gobuffalo/pop/soda
配置#
配置文件默认在 config/database.yaml
development:
dialect: "mysql"
database: "cokecoke"
host: "localhost"
port: "3306"
user: "root"
password: ""
创建模型#
pop 提供一个实用工具 soda。用 soda 可以创建模型。
$ soda generate model user title:string first_name:string last_name:string bio:text -e development
v3.41.1
--> models/user.go
--> models/user_test.go
--> goimports -w models/user.go models/user_test.go
> migrations/20171218173819_create_users.up.fizz
> migrations/20171218173819_create_users.down.fizz
soda 创建了两个文件夹:models 和 migrations。用户模型存储在其中 models/user.go,初始迁移存储在 migrations/20171218173819_create_users.up.fizz。fizz 下面会讲到如何使用。
创建数据#
-e development 代表创建开发环境下的数据库,当然也可以是 test 和 production。
$ soda create -e development
完成 fizz#
编辑 migrations/20171218173819_create_users.up.fizz 文件
create_table("users") {
t.Column("id", "uuid", {primary: true})
t.Timestamps()
t.Column("name", "string", {})
t.Column("email", "string", {})
t.Column("password_hash", "string", {"size":64})
t.Column("register_time", "timestamp", {"default": null})
t.Column("last_login_time", "timestamp", {"default": null})
}
add_index("users", "name", {"unique": true})
add_index("users", "email", {"unique": true})
运行迁移#
完成了迁移的 fizz 文件,就可以执行迁移
soda migrate up -e development
这样,我们的数据库,数据表都已经创建完成了。
修改表结构#
项目执行过程中,由于这样那样的原因,难免表结构会改变。比如我们需要给用户表填一个 location 字段
soda generate fizz user_location_column
会生成一个 20171219202712_user_add_location_column.up.fizz 文件。
add_column("user", "location", "string", {"size": 100, "default": "New York, NY"})
为了恢复版本变化,我们需要修改 20171219202712_user_add_location_column.down.fizz 文件。
drop_column("user", "location")
现在您需要更新实际模型
type User struct {
ID uuid.UUID `json:"id" db:"id"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
Name string `json:"name" db:"name"`
Email string `json:"email" db:"email"`
PasswordHash string `json:"password_hash" db:"password_hash"`
Password string `json:"-" db:"-"`
PasswordConfirmation string `json:"-" db:"-"`
Location string `json:"location" db:"location"` // 这行是新增的
}
再次运行迁移
$ soda migrate up -e development
表结构修改完成,
连接数据库#
tx, err := pop.Connect("development")
if err != nil {
log.Panic(err)
}
创建新纪录#
jessica := models.User{
Title: "Ms.",
FirstName: "Jessica",
LastName: "Jones",
Bio: "Private security, super hero.",
}
_, err = tx.ValidateAndSave(&jessica)
if err != nil {
log.Panic(err)
}
按 ID 查询一条记录#
id := "240ec3c5-019d-4031-9c27-8a553e022297" // frank
frank := models.User{}
err = tx.Find(&frank, id)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
fmt.Print("Success!\n")
fmt.Printf("%v\n", frank)
}
查询所有记录#
users := []models.User{}
err = tx.All(&users)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
fmt.Print("Success!\n")
fmt.Printf("%v\n", users)
}
查询某些数据#
query := tx.Where("last_name = 'Rand' OR last_name = 'Murdock'")
users := []models.User{}
err = query.All(&users)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
fmt.Print("Success!\n")
fmt.Printf("%v\n", users)
}
更新单个记录#
query := tx.Where("title = 'Ms.'")
users := []models.User{}
err = query.All(&users)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
for i := 0; i < len(users); i++ {
user := users[i]
user.Title = "Mrs."
tx.ValidateAndSave(&user)
fmt.Print("Success!\n")
fmt.Printf("%v\n", user)
}
}
更新多个记录#
更新多个记录与更新单个记录非常相似
users := []models.User{}
err = tx.All(&users)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
for i := 0; i < len(users); i++ {
user := users[i]
user.Location = "NYC, NY"
tx.ValidateAndSave(&user)
fmt.Print("Success!\n")
fmt.Printf("%v\n", user)
}
}
删除单个记录#
id := "240ec3c5-019d-4031-9c27-8a553e022297"
frank := models.User{}
err = tx.Find(&frank, id)
if err != nil {
fmt.Print("ERROR!\n")
fmt.Printf("%v\n", err)
} else {
fmt.Print("Success! - Now delete it.\n")
tx.Destroy(&frank)
}
删除多条记录#
删除多条记录与删除单条记录非常相似,不列出来了。
推荐文章: