结构查问条件
worm 是一款不便易用的 Go 语言 ORM 库。worm 支 Model 形式(持构造体字段映射)、原生 SQL 以及 SQLBuilder 三种模式来操作数据库,并且 Model 形式、原生 SQL 以及 SQLBuilder 可混合应用。
Model 形式、SQL builder 反对链式 API,可应用 Where, And, Or, ID, In, Limit, GroupBy, OrderBy, Having 等函数结构查问条件。也能够可通过 Join、LeftJoin、RightJoin 来进行数据库表之间的关联查问。
本文通过一些例子来阐明如何应用 worm 来结构查问条件。
main 函数
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
log "github.com/haming123/wego/dlog"
"github.com/haming123/wego/worm"
)
func mysql_open(cnnstr string) (*sql.DB, error) {db, err := sql.Open("mysql", cnnstr)
if err != nil {return nil, err}
err = db.Ping()
if err != nil {return nil, err}
return db, nil
}
func main() {
// 创立数据连接池
cnnstr := "user:passwd@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True"
db_cnn, err := mysql_open(cnnstr)
if err != nil {log.Error(err)
return
}
// 初始化 ORM
worm.InitMysql(db_cnn)
// 显示 SQL 语句 log
worm.ShowSqlLog(true)
}
阐明:
- worm 代码的下载
go get github.com/haming123/wego - worm.ShowSqlLog
worm.ShowSqlLog 用于管制 sql 日志的显示,倡议测试环境下关上 sql 日志的显示的开关,这样能够看到每个数据库操作的 sql 语句以及执行工夫,不便疾速定位问题。 - 数据库的反对
目前 worm 反对的数据库有:mysql、postgres、sqlite、sqlserver,本文的例子中采纳了 mysql 数据库。
数据库表与数据模型
// 建表语句
CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`passwd` varchar(32) DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
);
数据库表 user 对应的实体类的定义如下:
type User struct {
Id int64 `db:"id;autoincr"`
Name string `db:"name"`
Age int64 `db:"age"`
Passwd string `db:"passwd"`
Created time.Time `db:"created;n_update"`
}
func (ent *User) TableName() string {return "user"}
阐明:
- worm 应用名称为 ”db” 的 Tag 映射数据库字段,”db” 前面是字段的名称,autoincr 用于阐明该字段是自增 ID,n_update 用于阐明该字段不可用于 update 语句中。
通过 ID 来查问数据
若数据库表存在 id
字段,则能够通过 ID 函数来查问一条数据据记录:
func DemoGetById() {
var user model.User
_, err := worm.Model(&user).ID(1).Get()
if err != nil {log.Error(err)
return
}
log.Debug(user)
}
//select id,name,age,passwd,created from user where id=? limit 1
执行该函数后的 sql 日志为:
[S] select id,name,age,passwd,created from user where id=1 limit 1
[S] DB: time=18.816ms
通过 Where 函数来查问数据
Where 函数的应用相似 Sprintf 函数,函数的第一个参数是 sql 语句 (where 语句) 模板,前面的参数是模板变量的值。
func DemoWhere() {var users []model.User
err := worm.Model(&model.User{}).Where("id>? and age>?", 1, 10).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为://select id,name,age,passwd,created from user where id>? and age>?
阐明:
- worm 占位符对立应用?,worm 会依据数据库类型, 主动替换占位符,例如 postgresql 数据库把? 替换成 $1,$2…
- 能够在 Where 函数应用多个变量进行查问,这种形式比拟直观,与数据库查问中的 sql 语句的写法比拟相似。然而当查问条件比拟多时,倡议应用 And、OR 函数进行适当的宰割,避免将查问变量与变量的值对应谬误。例如:
func DemoWhere2() {var users []model.User
err := worm.Model(&model.User{}).Where("id>?", 1).And("age>?", 10).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为://select id,name,age,passwd,created from user where id>? and age>?
-
like 查问的写法
例如查问用户的姓名中蕴含:demo
的数据库记录:func DemoWhereLike() {var users []model.User err := worm.Model(&model.User{}).Where("name like ?", "%demo%").Find(&users) if err != nil {log.Error(err) return } } // 对应的 sql 语句为://select id,name,age,passwd,created from user where name like '%demo%'
XXXIf 查问
有些状况加咱们会依据变量的值来判断应用应用一个变量来作为查问条件来查问书库,例如,若用户的姓名不为空时通过用户姓名来查询数据库。惯例的写法如下:
func DemoWhereIf(name string) {var users []model.User
var err error
if name == "" {err = worm.Model(&model.User{}).Find(&users)
} else {err = worm.Model(&model.User{}).Where("name=?", name).Find(&users)
}
if err != nil {log.Error(err)
return
}
}
worm 提供了更为简略的办法(提供了 WhereIf、AndIf、OrIf 函数)来反对这种查问需要:
func DemoWhereIf(name string) {var users []model.User
err := worm.Model(&model.User{}).WhereIf(name != "","name=?", name).Find(&users)
if err != nil {log.Error(err)
return
}
}
阐明:
- WhereIf 函数的第一个参数时一个 bool 变量,若该变量为 true,则会增加查问条件,否则疏忽该查问条件。
in、not in 查问
worm 提供了 AndIn、AndNotIn、OrIn、OrNotIn 函数来反对 sql 语句中的 in、not in 查问。例如:
func DemoWhereIn() {var users []model.User
err := worm.Model(&model.User{}).Where("").AndIn("id", 11, 12, 13, 14).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为:select id,name,age,passwd,created from user where id in (?,?,?,?)
XXXIn、XXXNotIn 的第二个参数时一个变长参数,您能够将须要查问的值作为变长参数传入,也能够将查问的值放到一个数组中进行查问:
func DemoWhereIn() {var users []model.User
arr_id := []int64{11, 12, 13, 14}
err := worm.Model(&model.User{}).Where("").AndIn("id", arr_id).Find(&users)
if err != nil {log.Error(err)
return
}
}
阐明:
- 若应用数组形式,则可变长参数智能时一个参数,并且该参数为数组类型。
嵌套查问语句
worm 反对嵌套查问语句,例如查问为:age>10 and (name='demo1' or name='demo2')
,则应用 worm 的形式如下:
func DemoWhereExp() {var users []model.User
sqlw := worm.SQLW("name=?", "demo1").Or("name=?", "demo2")
err := worm.Model(&model.User{}).Where("age>?", 10).AndExp(sqlw).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为://select id,name,age,passwd,created from user where age>? and (name=? or name=?)
Limit 与 Offset
在 MySQL 语句中能够应用 Limit 与 Offset 来查询数据库,这种查问通常用于 WEB 的分页查问中。worm 也反对 mysql 的 Limit 与 Offset 语句:
func DemoQueryPage(plen int64, pcur int64) {var users []model.User
err := worm.Model(&model.User{}).Where("age>?", 10).Limit(plen).Offset(plen * pcur).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为://select id,name,age,passwd,created from user where age>? limit ?, ?
orderby 查问
OrderBy 函数对应 sql 语句中的 order by 语句:
func DemoQueryOrderBy(orderby string) {var users []model.User
err := worm.Model(&model.User{}).Where("age>?", 10).OrderBy(orderby).Find(&users)
if err != nil {log.Error(err)
return
}
}
// 对应的 sql 语句为://select id,name,age,passwd,created from user where age>? order by created desc