NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

AboutMulti-DriverSQL Files
Query Objects OverviewListQueryGetQueryValueQueryMapsQuery
DBQueryingLow Level Query

Query Objects Overview

Learn how to use db.Query values with ListQuery, GetQuery, ValueQuery, and MapsQuery.

Query object helpers are the lower-level version of the select helpers.

Instead of passing a query string and arguments directly into db.List, db.Get, db.Value, or db.Maps, you first create a db.Query value and then execute it.

This is useful when you want to prepare a query once and pass it between functions.

Available Helpers

HelperResultUse case
db.Rawdb.QueryCreate a query object from SQL/CQL and arguments
db.ListQuery[T][]TRead multiple rows from a db.Query
db.GetQuery[T](T, bool, error)Read zero or one row from a db.Query
db.ValueQuery[T](T, bool, error)Read one scalar value from a db.Query
db.MapsQuery[]map[string]anyRead map rows from a db.Query

Basic Flow

Create a query object with db.Raw.

q, err := db.Raw(`
	SELECT * FROM users
	WHERE active = ?
	ORDER BY created_at DESC
`, true)

if err != nil {
	return nil, err
}

Then pass the query object to one of the query helpers.

users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
	return nil, err
}

This is equivalent to:

users, err := db.List[User](ctx, conn, `
	SELECT * FROM users
	WHERE active = ?
	ORDER BY created_at DESC
`, true)

Why Use Query Objects?

Use query objects when the query is built or selected before execution.

Common use cases include:

  • passing a query between application layers
  • building small query helper functions
  • selecting SQL from another source before execution
  • using db.Dialect before calling ListQuery, GetQuery, ValueQuery, or MapsQuery
  • keeping repository functions focused on execution
  • reusing the same query object in tests

Query Object Shape

A db.Query contains the SQL or CQL string and its arguments.

type Query struct {
	SQL  string
	Args []any
	Type int
}

Most application code creates it through db.Raw.

q, err := db.Raw(query, args...)

db.Raw validates that the query string is not empty.

If the query string is empty, it returns an error.

ListQuery

Use db.ListQuery when the query object should return multiple typed rows.

users, err := db.ListQuery[User](ctx, conn, q)
if err != nil {
	return nil, err
}

This is the query-object equivalent of db.List.

GetQuery

Use db.GetQuery when the query object should return zero or one typed row.

user, found, err := db.GetQuery[User](ctx, conn, q)
if err != nil {
	return User{}, false, err
}

if !found {
	return User{}, false, nil
}

This is the query-object equivalent of db.Get.

ValueQuery

Use db.ValueQuery when the query object should return one scalar value.

total, found, err := db.ValueQuery[int64](ctx, conn, q)
if err != nil {
	return 0, false, err
}

This is the query-object equivalent of db.Value.

MapsQuery

Use db.MapsQuery when the query object should return dynamic map rows.

rows, err := db.MapsQuery(ctx, conn, q)
if err != nil {
	return nil, err
}

This is the query-object equivalent of db.Maps.

Placeholder Differences

Query objects do not change SQL placeholder syntax.

The query string must still match the selected driver.

DriverPlaceholder style
MySQL?
Postgres$1, $2, $3
Scylla?

Example MySQL query object:

q, err := db.Raw(`
	SELECT * FROM users
	WHERE active = ?
`, true)

Example PostgreSQL query object:

q, err := db.Raw(`
	SELECT * FROM users
	WHERE active = $1
`, true)

Query Objects and Dialect SQL

Query objects are also useful with dialect SQL.

db.Dialect selects the correct SQL or CQL string from a db.DialectSQL value and returns a db.Query.

q, err := db.Dialect(conn, queries.GetUser, id)
if err != nil {
	return User{}, false, err
}

return db.GetQuery[User](ctx, conn, q)

This is useful when the query comes from SQL model files and your application may run on different drivers.

Choosing the Right Helper

NeedUse
Create a query objectdb.Raw
Multiple typed rows from a query objectdb.ListQuery[T]
Zero or one typed row from a query objectdb.GetQuery[T]
One scalar value from a query objectdb.ValueQuery[T]
Dynamic map rows from a query objectdb.MapsQuery

Select Helpers vs Query Objects

Use select helpers for direct application code.

users, err := db.List[User](ctx, conn, query, args...)

Use query objects when you want a separate query creation step.

q, err := db.Raw(query, args...)
if err != nil {
	return nil, err
}

users, err := db.ListQuery[User](ctx, conn, q)

Next Step

Continue with the dedicated query-object pages for complete examples of:

  • ListQuery
  • GetQuery
  • ValueQuery
  • MapsQuery

Maps

Use db.Maps to read database rows as dynamic map values.

ListQuery

Use db.ListQuery to read multiple database rows from a prepared db.Query value.

On this page

Available HelpersBasic FlowWhy Use Query Objects?Query Object ShapeListQueryGetQueryValueQueryMapsQueryPlaceholder DifferencesQuery Objects and Dialect SQLChoosing the Right HelperSelect Helpers vs Query ObjectsNext Step