Использовали ли вы query builder для SQL запросов
Что проверяют
Есть ли у вас практический опыт работы с базой из Go и понимаете ли вы, где конструктор запросов полезен, а где лишний. Следом обычно просят показать, какой SQL получился на выходе, и спрашивают, чем builder отличается от ORM и от sqlc.
Как отвечать
Сначала разведите инструменты, в Go их часто путают:
database/sqlиpgx: чистый SQL с плейсхолдерами,pgx/v5сейчас стандарт для PostgreSQL;sqlx: тот же SQL, но с удобным сканированием строк в структуры;- query builder:
squirrelилиgoquсобирают SQL в коде,sq.Select("id", "name").From("users").Where(sq.Eq{"role": role}), аToSql()возвращает строку и аргументы. Для PostgreSQL нуженPlaceholderFormat(sq.Dollar); - кодогенерация: в
sqlcвы пишете SQL-файлы и получаете типобезопасные функции; - ORM:
gorm,ent,bunработают с моделями и связями, SQL генерируется за вас.
Builder оправдан там, где запрос собирается динамически: фильтры каталога из параметров запроса, необязательные условия, сортировка, пагинация. Без него это склейка строк и ручной подсчёт $1, $2. Для статичных запросов проще чистый SQL или sqlc.
Расскажите свой случай: какая задача, почему выбрали builder, что получилось и что мешало. Хорошие детали: логировали результат ToSql() при отладке, проверяли план через EXPLAIN ANALYZE, закрыли сортировку белым списком колонок. Если builder не использовали, скажите честно и опишите, как решали динамические запросы руками: срез аргументов, счётчик плейсхолдеров, тесты на сборку строки.
Где спотыкаются
Называют gorm конструктором запросов. Это ORM со своими издержками: скрытые запросы, N+1, неожиданный SQL.
Считают, что builder сам защищает от SQL-инъекций. Значения он параметризует, но имя колонки для ORDER BY из параметров запроса или строка внутри sq.Expr уйдут в SQL как есть.
Оборачивают в builder все запросы подряд. Простой SELECT по ключу превращается в цепочку вызовов, которую читать труднее, чем исходный SQL.