如果你想在结构体中添加一个 time.Time
类型的字段,同时仍然希望能够在动态生成 WHERE 子句时考虑到这个字段,你可以简单地将该字段加入到结构体中,并在 generateWhereClause
函数中进行相应的处理。以下是修改后的例子:
package main
import (
"fmt"
"log"
"strings"
"time"
"github.com/jmoiron/sqlx"
_ "github.com/go-sql-driver/mysql"
)
// 定义一个示例的结构体
type Person struct {
ID int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
Location string `db:"location"`
Birthdate time.Time `db:"birthdate"`
}
// 生成 WHERE 子句的函数
func generateWhereClause(obj interface{}) (string, map[string]interface{}) {
params := make(map[string]interface{})
var conditions []string
v := sqlx.Named(obj)
for key, value := range v {
// 判断值是否为空
if value == nil || isEmpty(value) {
continue
}
// 特殊处理 time.Time 类型的字段
if _, ok := value.(time.Time); ok {
conditions = append(conditions, fmt.Sprintf("%s=:%s", key, key))
params[key] = value
continue
}
conditions = append(conditions, fmt.Sprintf("%s=:%s", key, key))
params[key] = value
}
whereClause := strings.Join(conditions, " AND ")
return whereClause, params
}
// 判断值是否为空的辅助函数
func isEmpty(value interface{}) bool {
switch v := value.(type) {
case int:
return v == 0
case string:
return v == ""
case time.Time:
return v.IsZero()
default:
return false
}
}
func main() {
// 数据库连接信息
dsn := "username:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
// 打开数据库连接
db, err := sqlx.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 创建一个示例的结构体
person := Person{
ID: 1,
Name: "John Doe",
// Age is intentionally left empty
Location: "New York",
Birthdate: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
}
// 生成 WHERE 子句和命名参数
whereClause, params := generateWhereClause(person)
// 构建 SQL 语句
sqlStatement := fmt.Sprintf("SELECT * FROM table_name WHERE %s", whereClause)
// 执行查询
rows, err := db.NamedQuery(sqlStatement, params)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// 处理查询结果...
}
在这个示例中,我给 Person
结构体添加了一个 Birthdate
字段,并在 generateWhereClause
函数中特殊处理了 time.Time
类型的字段。在 isEmpty
辅助函数中,我使用了 IsZero
方法来判断 time.Time
类型字段是否为空。你可以根据你的需求调整这些逻辑。