feat(repo): 添加SQL语句执行日志功能

- 新增LoggedStmt结构体封装sql.Stmt以支持日志记录
- 在SQL命令加载时注入日志功能
- 实现ExecContext、QueryContext和QueryRowContext方法的日志记录- 修改GetCategoryPageCount字段类型为*LoggedStmt
- 调整scanProduct和scanProducts函数实现以提高代码可读性- 新增getSQLQuery函数用于读取SQL命令文件内容
-为多个SQL执行方法添加调试日志输出
This commit is contained in:
2025-11-08 19:44:48 +08:00
parent 1f1632588d
commit dc9eddc638
5 changed files with 79 additions and 18 deletions

View File

@@ -36,7 +36,8 @@ func loadCommands(db *sql.DB, config config.Configuration, logger logging.Logger
commandName := commandType.Field(i).Name
logger.Debugf("Loading SQL command: %v", commandName)
stmt := prepareCommand(db, commandName, config, logger)
commandVal.Field(i).Set(reflect.ValueOf(stmt))
loggedStmt := NewLoggedStmt(stmt, getSQLQuery(commandName, config), logger)
commandVal.Field(i).Set(reflect.ValueOf(loggedStmt))
}
return commands
}
@@ -56,3 +57,15 @@ func prepareCommand(db *sql.DB, command string, config config.Configuration, log
}
return statement
}
func getSQLQuery(command string, config config.Configuration) string {
fileName, found := config.GetString("sql:commands:" + command)
if !found {
return ""
}
data, err := os.ReadFile(fileName)
if err != nil {
return ""
}
return string(data)
}

View File

@@ -0,0 +1,51 @@
package repo
import (
"context"
"database/sql"
"platform/logging"
)
// LoggedStmt 包装sql.Stmt以添加日志功能
type LoggedStmt struct {
*sql.Stmt
query string
logger logging.Logger
}
// LoggedRows 包装sql.Rows
type LoggedRows struct {
*sql.Rows
}
// LoggedRow 包装sql.Row
type LoggedRow struct {
*sql.Row
}
// NewLoggedStmt 创建一个新的LoggedStmt实例
func NewLoggedStmt(stmt *sql.Stmt, query string, logger logging.Logger) *LoggedStmt {
return &LoggedStmt{
Stmt: stmt,
query: query,
logger: logger,
}
}
// ExecContext 记录并执行ExecContext
func (ls *LoggedStmt) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) {
ls.logger.Debugf("Executing SQL: %s, params: %v", ls.query, args)
return ls.Stmt.ExecContext(ctx, args...)
}
// QueryContext 记录并执行QueryContext
func (ls *LoggedStmt) QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) {
ls.logger.Debugf("Executing SQL: %s, params: %v", ls.query, args)
return ls.Stmt.QueryContext(ctx, args...)
}
// QueryRowContext 记录并执行QueryRowContext
func (ls *LoggedStmt) QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row {
ls.logger.Debugf("Executing SQL: %s, params: %v", ls.query, args)
return ls.Stmt.QueryRowContext(ctx, args...)
}

View File

@@ -24,5 +24,5 @@ type SqlCommands struct {
GetPage,
GetPageCount,
GetCategoryPage,
GetCategoryPageCount *sql.Stmt
GetCategoryPageCount *LoggedStmt
}

View File

@@ -5,23 +5,20 @@ import (
"sportstore/models"
)
func scanProducts(rows *sql.Rows) (products []models.Product, err error) {
products = make([]models.Product, 0, 10)
for rows.Next() {
p := models.Product{Category: &models.Category{}}
if err = rows.Scan(&p.ID, &p.Name, &p.Description, &p.Price,
&p.Category.ID, &p.Category.CategoryName); err == nil {
products = append(products, p)
} else {
return
}
}
func scanProduct(row *sql.Row) (p models.Product, err error) {
p.Category = &models.Category{}
err = row.Scan(&p.ID, &p.Name, &p.Description, &p.Price, &p.Category.ID, &p.Category.CategoryName)
return
}
func scanProduct(row *sql.Row) (p models.Product, err error) {
p = models.Product{Category: &models.Category{}}
err = row.Scan(&p.ID, &p.Name, &p.Description, &p.Price,
&p.Category.ID, &p.Category.CategoryName)
return p, err
func scanProducts(rows *sql.Rows) (results []models.Product, err error) {
for rows.Next() {
p := models.Product{}
p.Category = &models.Category{}
if err = rows.Scan(&p.ID, &p.Name, &p.Description, &p.Price, &p.Category.ID, &p.Category.CategoryName); err != nil {
return
}
results = append(results, p)
}
return
}

Binary file not shown.