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

ListQuery

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

Use db.ListQuery when you already have a db.Query value and expect multiple rows.

It scans all returned rows into a typed Go slice.

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

ListQuery is the query-object version of db.List.

Function

func ListQuery[T any](ctx context.Context, c db.Querier, q db.Query) ([]T, error)

ListQuery accepts:

  • a context.Context
  • a connection or query-capable value
  • a db.Query

It returns:

[]T, error

When to Use ListQuery

Use db.ListQuery when:

  • you already created a db.Query
  • the query can return zero or more rows
  • the result shape is known
  • you want a typed []T
  • query creation and query execution are separate steps
  • the query was created by db.Raw or db.Dialect

For direct query strings, use db.List.

Define a Model

type User struct {
	ID        int64     `db:"id"`
	Name      string    `db:"name"`
	Email     string    `db:"email"`
	Active    bool      `db:"active"`
	CreatedAt time.Time `db:"created_at"`
}

Create a Query Object

Create a db.Query using db.Raw.

For MySQL and Scylla, use ? placeholders.

const selectUsersQuery = `
	SELECT *
	FROM users
	ORDER BY created_at DESC
	LIMIT ?
`
q, err := db.Raw(selectUsersQuery, 10)
if err != nil {
	return nil, err
}

For PostgreSQL, the query uses numbered placeholders.

const selectUsersQuery = `
	SELECT *
	FROM users
	ORDER BY created_at DESC
	LIMIT $1
`

The Go code stays the same:

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

Execute the Query Object

Pass the query object into db.ListQuery.

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

Complete Query Example

This example creates a db.Query and reads users as a typed slice.

package main

import (
	"context"
	"time"

	"github.com/netlifeguru/db"
)

type User struct {
	ID        int64     `db:"id"`
	Name      string    `db:"name"`
	Email     string    `db:"email"`
	Active    bool      `db:"active"`
	CreatedAt time.Time `db:"created_at"`
}

const selectUsersQuery = `
	SELECT *
	FROM users
	ORDER BY created_at DESC
	LIMIT ?
`

func ListUsersQuery(ctx context.Context, conn db.Conn, limit int) ([]User, error) {
	q, err := db.Raw(selectUsersQuery, limit)
	if err != nil {
		return nil, err
	}

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

Complete Usage Example

This example connects to the database, executes the query-object helper, and prints the result.

package main

import (
	"context"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
	"github.com/joho/godotenv"
)

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Println(".env file not found, I'm using system env variables")
	}

	conn, err := connectDB()
	if err != nil {
		log.Fatal(err)
	}

	ctx := context.Background()

	users, err := ListUsersQuery(ctx, conn, 10)
	if err != nil {
		log.Fatal(err)
	}

	for _, user := range users {
		fmt.Printf(
			"ID: %d | Name: %s | Email: %s | Active: %t | Created: %s\n",
			user.ID,
			user.Name,
			user.Email,
			user.Active,
			user.CreatedAt.Format("2006-01-02 15:04:05"),
		)
	}
}

Empty Results

If the query returns no rows, db.ListQuery returns an empty slice.

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

fmt.Println(len(users)) // 0

An empty result is not treated as an error.

Raw Query Validation

db.Raw returns an error when the query string is empty.

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

This prevents empty query objects from being executed accidentally.

Query Objects From Dialect SQL

ListQuery is often used together with db.Dialect.

q, err := db.Dialect(conn, queries.ListUsers, 10)
if err != nil {
	return nil, err
}

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

For direct dialect usage, you can also use db.ListDialect.

users, err := db.ListDialect[User](ctx, conn, queries.ListUsers, 10)

Related Helpers

Use db.List when you want to pass the query string directly.

users, err := db.List[User](ctx, conn, selectUsersQuery, 10)

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

user, found, err := db.GetQuery[User](ctx, conn, q)

Use db.ValueQuery when the query object returns one scalar value.

total, found, err := db.ValueQuery[int64](ctx, conn, q)

Use db.MapsQuery when the query object returns dynamic map rows.

rows, err := db.MapsQuery(ctx, conn, q)

Related Examples

Standalone examples are available in the examples repository:

  • Query List

Query Objects Overview

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

GetQuery

Use db.GetQuery to read zero or one database row from a prepared db.Query value.

On this page

FunctionWhen to Use ListQueryDefine a ModelCreate a Query ObjectExecute the Query ObjectComplete Query ExampleComplete Usage ExampleEmpty ResultsRaw Query ValidationQuery Objects From Dialect SQLRelated HelpersRelated Examples