0Pricing
Go Academy · Урок

Подготовленные операторы

Выполняйте параметризованные запросы

«Подготовленные операторы» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Что такое подготовленный оператор

Подготовленный оператор один раз отправляет текст SQL в базу данных для разбора и построения плана, а затем многократно выполняется с разными параметрами. Это быстрее при повторяющихся запросах и защищает от внедрения кода.

Заполнители параметров

Никогда не формируйте SQL конкатенацией пользовательского ввода. Используйте заполнители, чтобы драйвер передавал значения отдельно. PostgreSQL использует $1, $2, а MySQL и SQLite — ?.

SELECT * FROM users WHERE age > $1 AND city = $2

Почему это предотвращает внедрение

Поскольку параметры передаются отдельно от текста SQL, база данных обрабатывает их только как данные, а не как код. Вредоносное значение вроде " OR 1=1 становится строковым литералом, а не исполняемым SQL-кодом.

db.Prepare

Prepare возвращает объект *sql.Stmt, связанный с пулом. Затем вызывайте Exec или Query для этого оператора, передавая аргументы.

stmt, err := db.Prepare("INSERT INTO users(name, age) VALUES($1, $2)")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

Выполнение оператора

Вызовите stmt.Exec, передав аргумент для каждого заполнителя. Для вставок и обновлений Exec возвращает объект sql.Result с числом затронутых строк и ID последней вставленной записи.

res, err := stmt.Exec("Ada", 36)
if err != nil {
    log.Fatal(err)
}
n, _ := res.RowsAffected()
fmt.Println("inserted", n)

Повторное использование в цикле

Преимущество достигается за счёт повторного использования: подготовьте оператор один раз и многократно выполняйте его внутри цикла. База данных повторно использует разобранный план при каждом вызове.

for _, u := range users {
    if _, err := stmt.Exec(u.Name, u.Age); err != nil {
        log.Fatal(err)
    }
}

Неявная подготовка

Прямая передача аргументов в db.Query или db.Exec также безопасно использует заполнители; драйвер может выполнять подготовку внутри себя. Явный Prepare в основном нужен для многократного выполнения.

Рабочая симуляция привязки параметров

Для настоящих подготовленных выражений нужна база данных. Этот запускаемый пример моделирует безопасную привязку параметров и показывает, как значения остаются отделёнными от текста запроса.

package main

import "fmt"

func execPrepared(query string, args ...interface{}) string {
    return fmt.Sprintf("EXEC %q with args %v", query, args)
}

func main() {
    q := "INSERT INTO users(name, age) VALUES($1, $2)"
    people := [][2]interface{}{{"Ada", 36}, {"Lin", 41}}
    for _, p := range people {
        fmt.Println(execPrepared(q, p[0], p[1]))
    }
}

Варианты с контекстом

Используйте PrepareContext и stmt.ExecContext, чтобы подготовленные вызовы учитывали ограничения времени и отмену, как и остальные операции database/sql.

Всегда закрывайте подготовленное выражение

Объект *sql.Stmt удерживает ресурсы базы данных. После завершения работы отложите вызов stmt.Close(). Утечки выражений могут исчерпать серверное ограничение на число подготовленных выражений.

Выражения и пул соединений

Выражение, подготовленное для *sql.DB, работает с соединениями из пула; библиотека заново подготавливает его на том соединении, на котором оно окажется. Обычно Вам не нужно управлять этим самостоятельно.

Быстрая проверка

Проверьте свои знания о подготовленных выражениях.

Итоги

Вы изучили подготовленные выражения:

  • Prepare разбирает запрос один раз, а выполняет его много раз
  • Заполнители ($1 или ?) сохраняют значения как данные и предотвращают внедрение
  • Вызов Exec возвращает число затронутых строк; используйте отложенный вызов stmt.Close()
  • Повторно используйте выражения в циклах; для крайних сроков используйте варианты с контекстом

Часто задаваемые вопросы

Урок «Подготовленные операторы» бесплатный?

Да — полный текст урока «Подготовленные операторы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Подготовленные операторы»?

Выполняйте параметризованные запросы Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Подготовленные операторы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Открытие соединения
  2. Запрос строк
  3. Подготовленные операторы
  4. Транзакции
← Назад к Go Academy