Golang中如何使用gorm动态添加查询参数
Golang中如何使用gorm动态添加查询参数 我希望根据接收到的参数动态构建查询。例如,[SELECT (参数) FROM (参数) WHERE (参数)],而不是为每个用例反复编写查询,我希望使其完全动态化。最让我关注的部分是 WHERE 子句,因为它可能包含不同的查询操作(AND、OR、%LIKE 等)。
我希望使用 GORM 来实现这一点,以防止 SQL 注入。
func main() {
fmt.Println("hello world")
}
假设你的 QueryBuilder 函数完全按照你期望的方式工作,你会如何调用它并使用其结果?
更多关于Golang中如何使用gorm动态添加查询参数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我使用一个结构体来获取参数,并根据这些参数,通过将它们传递给一个QueryBuilder函数来生成结果。
我将展示我的代码,希望你能理解。我编写了一段代码,但这不是完成此任务的完美方式。有一个名为 DynamicQuery() 的函数,它获取 JSON 参数用于选择、条件、或操作,并将它们绑定到一个结构体中,之后我将其传递给第二个名为 QueryBuilder() 的函数。

现在,在第二个函数中,借助 sprint.f(),我构建了 db.where() 的结构,正如你通过代码所看到的,以便使用 ORM 运行它。我认为,过度使用 sprint.f() 会导致查询中容易受到 SQL 注入攻击。

在Golang中使用GORM动态构建查询参数,可以通过链式调用和条件构建来实现。以下是一个完整的示例:
package main
import (
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type User struct {
ID uint
Name string
Age int
Email string
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移
db.AutoMigrate(&User{})
// 动态查询示例
query := db.Model(&User{})
// 动态添加WHERE条件
conditions := map[string]interface{}{
"age > ?": 18,
"name LIKE ?": "%John%",
"email IS NOT NULL": nil,
}
for condition, value := range conditions {
if value == nil {
query = query.Where(condition)
} else {
query = query.Where(condition, value)
}
}
// 动态排序
query = query.Order("age DESC")
// 动态选择字段
query = query.Select("id, name, age")
// 执行查询
var users []User
if err := query.Find(&users).Error; err != nil {
fmt.Printf("查询失败: %v\n", err)
return
}
fmt.Printf("找到 %d 个用户\n", len(users))
}
// 更复杂的动态查询构建函数
func dynamicQuery(db *gorm.DB, filters map[string]interface{}) *gorm.DB {
query := db.Model(&User{})
for field, value := range filters {
switch field {
case "name":
if name, ok := value.(string); ok && name != "" {
query = query.Where("name LIKE ?", "%"+name+"%")
}
case "age_min":
if age, ok := value.(int); ok {
query = query.Where("age >= ?", age)
}
case "age_max":
if age, ok := value.(int); ok {
query = query.Where("age <= ?", age)
}
case "email":
if email, ok := value.(string); ok && email != "" {
query = query.Where("email = ?", email)
}
}
}
return query
}
// 使用Scopes进行动态查询
func WithFilters(filters map[string]interface{}) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
for key, value := range filters {
switch key {
case "search":
db = db.Where("name LIKE ? OR email LIKE ?",
"%"+value.(string)+"%",
"%"+value.(string)+"%")
case "active":
db = db.Where("active = ?", value)
}
}
return db
}
}
// 使用示例
func queryWithScopes(db *gorm.DB) {
var users []User
filters := map[string]interface{}{
"search": "john",
"active": true,
}
db.Scopes(WithFilters(filters)).Find(&users)
}
// 动态OR条件
func dynamicOrConditions(db *gorm.DB) {
var users []User
db.Where(
db.Where("name = ?", "John").Or("name = ?", "Jane"),
).Where("age > ?", 20).Find(&users)
}
// 使用clause进行复杂动态查询
func dynamicClauseQuery(db *gorm.DB, conditions []clause.Expression) *gorm.DB {
return db.Clauses(clause.Where{
Exprs: conditions,
})
}
// 构建动态表达式
func buildDynamicExpressions(params map[string]interface{}) []clause.Expression {
var exprs []clause.Expression
if name, ok := params["name"].(string); ok && name != "" {
exprs = append(exprs, clause.Like{
Column: "name",
Value: "%" + name + "%",
})
}
if age, ok := params["age"].(int); ok && age > 0 {
exprs = append(exprs, clause.Gt{
Column: "age",
Value: age,
})
}
return exprs
}
这个示例展示了多种动态构建查询的方法:
- 基础WHERE条件:使用
Where()方法链式调用 - 动态条件映射:通过map结构传递查询条件
- Scopes作用域:使用Scopes封装可复用的查询逻辑
- 复杂OR条件:动态构建OR查询
- Clause表达式:使用GORM的clause包构建复杂表达式
GORM会自动处理参数化查询,防止SQL注入。所有用户输入都会通过预编译语句处理,确保查询安全。


