package db import ( "allapp-go/pkg/logger" "context" "fmt" "strconv" "strings" "go.uber.org/zap" ) func (c *Client) LoadData( ctx context.Context, viewName string, searchCondition string, orderBy string, searchColumns []string, args []any, ) ([]map[string]any, error) { selectCols := "*" if len(searchColumns) > 0 { selectCols = strings.Join(searchColumns, ", ") } where := "" if searchCondition != "" { where = " WHERE " + searchCondition } order := "" if orderBy != "" { order = " ORDER BY " + orderBy } sql := fmt.Sprintf( "SELECT %s FROM %s%s%s", selectCols, viewName, where, order, ) logger.FromCtx(ctx).Info("LoadData", zap.String("sql", sql), zap.Any("args", args), ) return c.query(ctx, sql, args...) } func (c *Client) LoadDataPage( ctx context.Context, viewName string, searchCondition string, orderBy string, searchColumns []string, args []any, page int, pageSize int, ) ([]map[string]any, int, error) { selectCols := "*" if len(searchColumns) > 0 { selectCols = strings.Join(searchColumns, ", ") } where := "" if searchCondition != "" { where = " WHERE " + searchCondition } // 1. COUNT 查询 countSQL := fmt.Sprintf("SELECT COUNT(*) FROM %s%s", viewName, where) countSQL = convertPlaceholder(countSQL) var total int err := c.pool.QueryRow(ctx, countSQL, args...).Scan(&total) if err != nil { return nil, 0, err } // 2. 分页数据查询 order := "" if orderBy != "" { order = " ORDER BY " + orderBy } offset := (page - 1) * pageSize dataSQL := fmt.Sprintf( "SELECT %s FROM %s%s%s LIMIT %d OFFSET %d", selectCols, viewName, where, order, pageSize, offset, ) logger.FromCtx(ctx).Info("LoadDataPage", zap.String("countSQL", countSQL), zap.String("dataSQL", dataSQL), zap.Any("args", args), zap.Int("total", total), ) rows, err := c.query(ctx, dataSQL, args...) if err != nil { return nil, 0, err } return rows, total, nil } func (c *Client) LoadDataBySQL( ctx context.Context, sql string, args []any, ) ([]map[string]any, error) { logger.FromCtx(ctx).Info("LoadDataBySQL", zap.String("sql", sql), zap.Any("args", args), ) return c.query(ctx, sql, args...) } func (c *Client) query(ctx context.Context, sql string, args ...any) ([]map[string]any, error) { sql = convertPlaceholder(sql) rows, err := c.pool.Query(ctx, sql, args...) if err != nil { return nil, err } defer rows.Close() fields := rows.FieldDescriptions() result := make([]map[string]any, 0, 16) for rows.Next() { values, err := rows.Values() if err != nil { return nil, err } row := make(map[string]any, len(values)) for i := range fields { if i < len(values) { row[string(fields[i].Name)] = values[i] } } result = append(result, row) } if err := rows.Err(); err != nil { return nil, err } return result, nil } func convertPlaceholder(sql string) string { var sb strings.Builder sb.Grow(len(sql)) argIndex := 1 for i := 0; i < len(sql); i++ { if sql[i] == '?' { sb.WriteByte('$') sb.WriteString(strconv.Itoa(argIndex)) argIndex++ } else { sb.WriteByte(sql[i]) } } return sb.String() }