Go语言ORM库Worm构造查询条件示例详解
本文以Go语言ORM库worm为例,详细演示了如何借助其链式API构造各类复杂的数据库查询条件。内容涵盖ID定位、Where基础匹配、Like模糊检索、动态条件If判断、In集合操作、嵌套逻辑以及分页排序等功能,通过Go代码与生成的SQL对比,帮助开发者掌握高效的数据查询方法。
结果与目标
在Go语言后端开发中,直接使用原生SQL容易引发维护困难与注入风险,而使用ORM框架可以大幅提升编码效率。worm是一款支持结构体映射(Model方式)、原生SQL及SQLBuilder模式的ORM库。本文将重点展示如何利用其链式API优雅地构造查询条件,解决常见数据库访问需求。
准备条件
第1步:初始化连接与日志配置
在使用worm之前,需要先建立数据库连接池并进行ORM框架的初始化建议开启SQL日志开关,以便在测试阶段观察实际执行的SQL语句及其耗时,便于调试和性能分析。
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() {
// 创建数据连接池,此处以MySQL为例
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语句日志,方便排查问题
worm.ShowSqlLog(true)
}
第2步:定义数据模型(Table Mapping)
worm通过Golang的结构体Tag来映射数据库表字段。使用db Tag指定字段名及特殊行为(如自增主键 autoincr 或更新忽略 n_update),需实现 TableName() 方法指明对应表名。
// 建表语句参考
// CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT, ...
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的Model方式和SQL Builder均支持链式调用。以下通过具体示例说明各场景的用法。
第1步:通过ID查询单条记录
若表中有主键ID,可直接利用 ID 函数定位。该方法自动添加 limit 1,适用于获取单条详情。
func DemoGetById() {
var user model.User
_, err := worm.Model(&user).ID(1).Get()
if err != nil { log.Error(err); return }
log.Debug(user)
}
// 生成SQL: select id,name,age,passwd,created from user where id=1 limit 1
第2步:使用Where进行常规筛选
Where 类似于 Sprintf,支持占位符。当条件简单时可直接传入;当条件增多时,建议使用链式的 And / Or 避免参数错位。
// 方式A:多变量直接放入Where
func DemoWhere() {
var users []model.User
err := worm.Model(&model.User{}).Where("id>? and age>?", 1, 10).Find(&users)
// SQL: ... where id>1 and age>10
}
// 方式B:链式拼接(推荐用于多条件)
func DemoWhere2() {
var users []model.User
err := worm.Model(&model.User{}).Where("id>?", 1).And("age>?", 10).Find(&users)
// SQL: ... where id>1 and age>10
}
// Like模糊查询
func DemoWhereLike() {
var users []model.User
err := worm.Model(&model.User{}).Where("name like ?", "%demo%").Find(&users)
// SQL: ... where name like '%demo%'
}
第3步:动态条件处理(If查询)
当业务需要根据前端传参是否为空来决定是否加入过滤条件时,传统写法需大量 if-else。worm提供了 WhereIf、AndIf 等方法简化此逻辑:
func DemoWhereIf(name string) {
var users []model.User
// 仅当 name != "" 时才添加该条件
err := worm.Model(&model.User{}).WhereIf(name != "", "name=?", name).Find(&users)
}
第4步:集合查询(In / Not In)
对于ID列表或多值筛选,可使用 AndIn、OrIn 等函数。支持变长参数或直接传入切片。
// 单个参数传递
func DemoWhereIn() {
var users []model.User
err := worm.Model(&model.User{}).Where("").AndIn("id", 11, 12, 13, 14).Find(&users)
// SQL: ... where id in (?,?,?,?)
}
// 数组切片传递
func DemoWhereInSlice() {
var users []model.User
arrID := []int64{11, 12, 13, 14}
err := worm.Model(&model.User{}).Where("").AndIn("id", arrID).Find(&users)
}
第5步:嵌套与分页排序
复杂逻辑嵌套(如 A AND (B OR C))可通过构建子查询对象实现;分页则结合 Limit 与 Offset,排序使用 OrderBy。
// 嵌套查询: age > 10 AND (name='demo1' OR name='demo2')
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)
}
// 分页查询
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)
// SQL: ... where age>? limit ?, ?
}
// 排序查询
func DemoQueryOrderBy() {
var users []model.User
err := worm.Model(&model.User{}).Where("age>?", 10).OrderBy("created desc").Find(&users)
// SQL: ... where age>? order by created desc
}
完成判断
检查终端输出的SQL日志是否准确反映了代码中构造的条件逻辑。同时确认返回的数据结构类型与预期一致,无报错信息。
简要总结
worm ORM库通过清晰的链式API极大地降低了Go语言编写数据库查询的复杂度。掌握了Where、If判定、In集合及嵌套逻辑后,即可应对绝大多数CRUD中的读取场景。以上就是Go语言ORM框架构造查询条件示例详解的详细内容,更多关于Go ORM构造查询条件的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













