Go: GORM
Теория: Условия выборки
Когда данных в таблице становится много, запрос вида «вернуть всё» быстро перестаёт быть полезным. Приложению нужны не тысячи строк сразу, а конкретные записи: пользователи старше определённого возраста, заказы по городам, события за последние дни. В SQL этим управляет оператор WHERE вместе с логическими связками AND, OR, NOT.
В GORM те же идеи выражены через методы Where(), Or(), Not() и Select(). Код остаётся на Go, а под капотом ORM собирает полный SQL-запрос.
Как GORM строит условия
GORM работает как конструктор. Каждый вызов Where() добавляет фильтр, Or() расширяет условия «или», Not() исключает значения, Select() управляет тем, какие поля попадут в результат. Вызовы можно соединять цепочкой — в финальном SQL GORM аккуратно расставит скобки, параметры и операторы.
Простейший пример: фильтр по возрасту.
Под капотом это превращается в:
Фильтр можно менять, не перестраивая SQL вручную — параметры подставятся безопасно.
Несколько условий: GORM сам склеит AND
Если критериев два и больше, приложение просто вызывает Where() ещё раз:
SQL:
Сама логика фильтра остаётся в коде Go, а про синтаксис SQL думает ORM.
Логическое «или»: Or
Or() добавляет условие, которое расширяет выборку.
SQL:
Так удобно собирать сложные правила, не превращая SQL в нечитаемую строку.
Исключение значений: Not
Если данные нужно не включить, а исключить, подходит Not():
SQL:
Можно передать карту:
SQL:
Работа с полями: Select
По умолчанию GORM выбирает все столбцы. Но часто нужны только несколько полей:
SQL:
Это ускоряет запросы и уменьшает объём данных.
Опасный момент: вычисляемые поля в модель User загружать нельзя
Иногда хочется посчитать что-то «на лету»:
Такой запрос нельзя мапить в модель User
GORM попытается заполнять структуру согласно именам колонок. Если поле age_in_months отсутствует, значение может попасть в другие поля модели, а Age перепишется. Итог — «возраст в месяцах» тихо портит «возраст в годах».
Правильный подход — отдельная структура под результат:
Модель User — только для полей таблицы. Любые вычисления выводим в отдельные DTO.
Условия из карты и структуры
Where() принимает не только строки с ?, но и карты:
SQL:
Если значение — срез, ORM строит IN. Структуры работают аналогично, но используют имена полей Go и теги gorm:"column:...".
Подводный камень: нулевые значения в структурах
Если фильтрация должна учитывать 0, пустую строку или false, структура не подходит: GORM пропускает такие поля. Именно поэтому структуры редко используют для динамических фильтров — проще карта.
Частые выражения: IN, LIKE, BETWEEN
Слетает без проблем:
Поиск подстроки:
Диапазоны:
Все параметры передаются безопасно — никакой конкатенации строк.
Что точно не нужно делать
Плохой вариант:
Такие строки:
- плохо читаются,
- легко ломаются,
- небезопасны (SQL-инъекции).
Правильный способ — WHERE age > ? или карта условий.
Как GORM собирает запрос внутри
Все вызовы Where(), Or(), Not(), Select() попадают в объект Statement. Перед выполнением GORM:
- собирает условия в единый SQL-текст,
- подставляет
?, - передаёт параметры отдельно в driver.
Код остаётся декларативным, а ORM собирает корректный SQL за вас.



