Modern SQL extensions for Go — a drop-in replacement for jmoiron/sqlx.
queryx provides a thin wrapper around Go's database/sql that adds struct scanning, named parameters, and convenience methods without ORM complexity.
- Struct scanning — scan rows directly into structs with
dbtags - Named parameters — use
:namesyntax in queries - Generic helpers — type-safe
Get[T]andSelect[T]functions - In clause expansion — expand slice arguments in
IN (?)clauses - Multiple bind formats —
$1(Postgres),?(MySQL/SQLite),@p1(MSSQL),:name(Oracle) - Context-first API — all methods require
context.Context - Fixed Postgres parsing — correctly handles
::typecasts and SQL comments - Zero reflect in hot path — aggressive struct field mapping cache
go get github.com/agentine/queryxRequires Go 1.22 or later.
package main
import (
"context"
"fmt"
"log"
"github.com/agentine/queryx"
_ "github.com/lib/pq"
)
type User struct {
ID int `db:"id"`
Name string `db:"name"`
Email string `db:"email"`
}
func main() {
ctx := context.Background()
db, err := queryx.Connect(ctx, "postgres", "postgres://localhost/mydb?sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Struct scanning with Get[T]
user, err := queryx.Get[User](ctx, db, "SELECT * FROM users WHERE id = $1", 1)
if err != nil {
log.Fatal(err)
}
fmt.Printf("User: %s <%s>\n", user.Name, user.Email)
// Query multiple rows with Select[T]
users, err := queryx.Select[User](ctx, db, "SELECT * FROM users WHERE name LIKE $1", "%alice%")
if err != nil {
log.Fatal(err)
}
for _, u := range users {
fmt.Printf(" %d: %s\n", u.ID, u.Name)
}
// Named parameters
_, err = db.NamedExecContext(ctx,
"INSERT INTO users (name, email) VALUES (:name, :email)",
map[string]interface{}{"name": "bob", "email": "bob@example.com"},
)
if err != nil {
log.Fatal(err)
}
// In clause expansion
query, args, err := queryx.In("SELECT * FROM users WHERE id IN (?)", []int{1, 2, 3})
if err != nil {
log.Fatal(err)
}
query = queryx.Rebind(queryx.DOLLAR, query)
var result []User
err = db.SelectContext(ctx, &result, query, args...)
if err != nil {
log.Fatal(err)
}
}queryx supports rebinding queries to different placeholder formats:
| Constant | Format | Databases |
|---|---|---|
queryx.QUESTION |
? |
MySQL, SQLite |
queryx.DOLLAR |
$1 |
PostgreSQL |
queryx.AT |
@p1 |
SQL Server |
queryx.NAMED |
:name |
Oracle |
queryx is designed as a drop-in replacement for jmoiron/sqlx. See MIGRATION.md for a detailed migration guide.
Key differences:
- Import
github.com/agentine/queryxinstead ofgithub.com/jmoiron/sqlx - All methods require
context.Context(no non-context variants) - New generic helpers:
Get[T]andSelect[T] - Fixed Postgres
::typecast parsing
MIT