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
Select OverviewListGetValueMaps
DBQueryingSelect

Select Overview

Learn the high-level select helpers for reading lists, single rows, scalar values, and map results.

The select helpers are the most common way to read data with the shared db package.

They are designed for everyday queries where you already have:

  • a context.Context
  • a db.Conn
  • a SQL or CQL query string
  • optional query arguments

The select helpers create a db.Query internally and execute it through the active driver.

Available Helpers

HelperResultUse case
db.List[T][]TRead multiple rows into a typed slice
db.Get[T](T, bool, error)Read zero or one row into a typed value
db.Value[T](T, bool, error)Read one scalar value
db.Maps[]map[string]anyRead rows as dynamic maps

These helpers are the highest-level read API.

For lower-level usage with db.Query, use the Query Objects helpers.

For SQL loaded from model files, use the Dialect SQL helpers.

List

Use db.List when the query returns multiple rows.

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

Example query for MySQL:

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

Example query for PostgreSQL:

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

Example query for Scylla:

const selectPostsByUserQuery = `
	SELECT *
	FROM posts_by_user
	WHERE user_id = ?
	LIMIT ?
`

db.List scans all returned rows into []T.

Get

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

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

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

Example query for MySQL:

const selectUserQuery = `
	SELECT *
	FROM users
	WHERE id = ?
	LIMIT 1
`

Example query for PostgreSQL:

const selectUserQuery = `
	SELECT *
	FROM users
	WHERE id = $1
	LIMIT 1
`

Example query for Scylla:

const selectUserByEmailQuery = `
	SELECT *
	FROM users_by_email
	WHERE email = ?
	LIMIT 1
`

db.Get returns:

value, found, err

found is false when the query returns no rows.

Value

Use db.Value when the query returns one scalar value.

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

if !found {
	return 0, false, nil
}

Example query:

const countUsersQuery = `
	SELECT COUNT(*)
	FROM users
`

Scylla example:

const countPostsByUserQuery = `
	SELECT COUNT(*)
	FROM posts_by_user
	WHERE user_id = ?
`

db.Value expects exactly one selected column.

It is useful for:

  • counts
  • IDs returned from RETURNING
  • flags
  • aggregate values
  • simple lookups

Maps

Use db.Maps when you want rows as dynamic map[string]any values.

rows, err := db.Maps(ctx, conn, selectUserMapsQuery, 10)
if err != nil {
	return nil, err
}

Example query for MySQL:

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

Example query for PostgreSQL:

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

Example query for Scylla:

const selectPostMapsByUserQuery = `
	SELECT *
	FROM posts_by_user
	WHERE user_id = ?
	LIMIT ?
`

db.Maps is useful for:

  • dynamic results
  • admin screens
  • reports
  • debugging
  • generic tooling

For stable application models, prefer db.List or db.Get.

Placeholder Differences

The Go helper API is the same across drivers, but SQL placeholders are still driver-specific.

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

Example MySQL call:

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

Example PostgreSQL call:

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

The Go code looks the same, but the query string uses the placeholder style required by the selected driver.

Choosing the Right Helper

NeedUse
Multiple typed rowsdb.List[T]
Zero or one typed rowdb.Get[T]
One scalar valuedb.Value[T]
Dynamic map rowsdb.Maps

Select Helpers vs Query Objects

The select helpers accept a raw query string and arguments directly.

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

Internally, they create a db.Query for you.

Use Query Objects when you want to build the query first:

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

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

Select Helpers vs Dialect SQL

Use select helpers when the query is written directly in Go code.

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

Use Dialect SQL helpers when the query comes from a loaded SQL model file.

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

Dialect SQL is useful when the same application can run with MySQL, PostgreSQL, or Scylla and each driver needs its own query text.

Recommended Usage

Start with the select helpers.

Use:

db.List[T]

for list endpoints.

Use:

db.Get[T]

for lookup endpoints.

Use:

db.Value[T]

for counts, aggregate values, or returned IDs.

Use:

db.Maps

when the result shape is dynamic.

Continue with the dedicated pages for each helper to see complete examples.

Pools

Understand connection pools, identifiers, shared pools, Fork, and Close behavior across DB drivers.

List

Use db.List to read multiple database rows into a typed Go slice.

On this page

Available HelpersListGetValueMapsPlaceholder DifferencesChoosing the Right HelperSelect Helpers vs Query ObjectsSelect Helpers vs Dialect SQLRecommended Usage