The DB struct is the central type in GORM. Every query, transaction, and database operation is performed through a *DB instance.
Type definition
type DB struct {
*Config
Error error
RowsAffected int64
Statement *Statement
clone int
}
Public fields
The last error that occurred on this DB instance. Always check this field (or the returned *DB) after finisher methods. Errors accumulate via AddError.
The number of rows affected by the last create, update, or delete operation. For queries it reflects the number of rows returned.
Open
func Open(dialector Dialector, opts ...Option) (db *DB, err error)
Initializes a new database session using the given dialector and optional configuration options. Open applies all options, initializes callbacks, connects the dialector, and (by default) pings the database to verify connectivity.
import (
"gorm.io/gorm"
"gorm.io/driver/postgres"
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("failed to connect to database:", err)
}
Open sorts options so that a *Config value is always applied first, before any other options.
Parameters
The database driver implementation. Import a driver package (e.g., gorm.io/driver/postgres) and call its Open function to obtain a Dialector.
Zero or more options. A *Config struct implements Option and is the standard way to configure GORM behaviour. Other options can modify individual config fields.
Utility methods
func (db *DB) DB() (*sql.DB, error)
Returns the underlying *sql.DB connection pool. Use this to set pool parameters such as SetMaxOpenConns, SetMaxIdleConns, and SetConnMaxLifetime.
sqlDB, err := db.DB()
if err != nil {
return err
}
sqlDB.SetMaxOpenConns(25)
sqlDB.SetMaxIdleConns(5)
WithContext
func (db *DB) WithContext(ctx context.Context) *DB
Returns a new *DB that uses the given context for all subsequent operations. Equivalent to db.Session(&Session{Context: ctx}).
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
var user User
db.WithContext(ctx).First(&user, 1)
Debug
func (db *DB) Debug() *DB
Returns a new *DB with the log level set to Info, causing all SQL statements to be printed. Useful during development.
db.Debug().Where("name = ?", "jinzhu").First(&user)
Session
func (db *DB) Session(config *Session) *DB
Creates a new session from the current DB, applying all settings in *Session. This is the primary way to create scoped DB instances that inherit the current state without mutating it. See Session for full field documentation.
tx := db.Session(&gorm.Session{
PrepareStmt: true,
Logger: myLogger,
})
Set / Get
func (db *DB) Set(key string, value interface{}) *DB
func (db *DB) Get(key string) (interface{}, bool)
Store and retrieve arbitrary values in the current statement’s shared settings map. Values set here are accessible to callbacks and plugins.
tx := db.Set("gorm:table_options", "ENGINE=InnoDB")
value, ok := tx.Get("gorm:table_options")
InstanceSet / InstanceGet
func (db *DB) InstanceSet(key string, value interface{}) *DB
func (db *DB) InstanceGet(key string) (interface{}, bool)
Like Set/Get, but keys are namespaced to the current *Statement pointer. This prevents key collisions when multiple statements share the same underlying settings map.
Callback
func (db *DB) Callback() *callbacks
Returns the callback manager, which lets you register, replace, or remove callbacks for the create, query, update, delete, and raw operations.
db.Callback().Create().Before("gorm:create").Register("my_plugin:before_create", func(db *gorm.DB) {
// custom logic
})
AddError
func (db *DB) AddError(err error) error
Appends an error to db.Error. If Config.TranslateError is enabled and the dialector implements ErrorTranslator, the error is translated before being stored. Subsequent errors are chained with fmt.Errorf("%v; %w", ...). Returns the current accumulated error.
Use
func (db *DB) Use(plugin Plugin) error
Registers a plugin with GORM. Calls plugin.Initialize(db) and stores the plugin by its name. Returns ErrRegistered if a plugin with the same name is already registered.
if err := db.Use(prometheus.New(prometheus.Config{})); err != nil {
log.Fatal(err)
}
SetupJoinTable
func (db *DB) SetupJoinTable(model interface{}, field string, joinTable interface{}) error
Configures a custom join table struct for a many-to-many relationship. The join table model can carry extra fields beyond the two foreign keys.
type UserFriend struct {
UserID uint
FriendID uint
Since time.Time
}
db.SetupJoinTable(&User{}, "Friends", &UserFriend{})
ToSQL
func (db *DB) ToSQL(queryFn func(tx *DB) *DB) string
Executes queryFn in dry-run mode and returns the generated SQL string with all bind variables interpolated. The database is not queried.
sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
return tx.Model(&User{}).Where("name = ?", "jinzhu").Find(&[]User{})
})
// sql => SELECT * FROM `users` WHERE name = 'jinzhu'
ToSQL skips the default transaction wrapper. Do not rely on transaction behaviour within queryFn.
Expr
func Expr(expr string, args ...interface{}) clause.Expr
Package-level function that wraps a raw SQL fragment and its arguments into a clause.Expr. Use it anywhere GORM accepts an interface{} value to pass a SQL expression instead of a literal.
// Increment a counter without loading the record
db.Model(&product).Update("price", gorm.Expr("price * ? + ?", 0.9, 10))
Generics API — G[T]
func G[T any](db *DB, opts ...clause.Expression) Interface[T]
G[T] is GORM’s type-safe generics API, available in Go 1.18+. It wraps a *DB and exposes all CRUD and query operations as strongly-typed methods that return T or []T directly — no type assertions or pointer scanning required.
import "gorm.io/gorm"
type User struct {
gorm.Model
Name string
Age int
}
// Create a type-safe query handle for User
users := gorm.G[User](db)
// First returns (User, error) — no pointer needed
user, err := users.Where("name = ?", "jinzhu").First(ctx)
// Find returns ([]User, error)
list, err := users.Where("age > ?", 18).Order("name ASC").Find(ctx)
// Create
err = users.Create(ctx, &User{Name: "jinzhu", Age: 20})
// Update — returns (rowsAffected int, err error)
n, err := users.Where("age < ?", 18).Update(ctx, "age", 18)
// Delete
n, err = users.Where("name = ?", "old").Delete(ctx)
Interface[T]
The top-level interface returned by G[T]:
type Interface[T any] interface {
Raw(sql string, values ...interface{}) ExecInterface[T]
Exec(ctx context.Context, sql string, values ...interface{}) error
CreateInterface[T]
}
ExecInterface[T]
Query execution methods returning typed results:
type ExecInterface[T any] interface {
First(context.Context) (T, error)
Last(ctx context.Context) (T, error)
Take(context.Context) (T, error)
Find(ctx context.Context) ([]T, error)
FindInBatches(ctx context.Context, batchSize int, fc func(data []T, batch int) error) error
Scan(ctx context.Context, r interface{}) error
Row(ctx context.Context) *sql.Row
Rows(ctx context.Context) (*sql.Rows, error)
}
ChainInterface[T]
Chainable query-building methods:
type ChainInterface[T any] interface {
ExecInterface[T]
Where(query interface{}, args ...interface{}) ChainInterface[T]
Not(query interface{}, args ...interface{}) ChainInterface[T]
Or(query interface{}, args ...interface{}) ChainInterface[T]
Select(query string, args ...interface{}) ChainInterface[T]
Omit(columns ...string) ChainInterface[T]
Order(value interface{}) ChainInterface[T]
Limit(offset int) ChainInterface[T]
Offset(offset int) ChainInterface[T]
Distinct(args ...interface{}) ChainInterface[T]
Group(name string) ChainInterface[T]
Having(query interface{}, args ...interface{}) ChainInterface[T]
Joins(query clause.JoinTarget, on func(db JoinBuilder, joinTable clause.Table, curTable clause.Table) error) ChainInterface[T]
Preload(association string, query func(db PreloadBuilder) error) ChainInterface[T]
MapColumns(m map[string]string) ChainInterface[T]
Scopes(scopes ...func(db *Statement)) ChainInterface[T]
Table(name string, args ...interface{}) ChainInterface[T]
Delete(ctx context.Context) (rowsAffected int, err error)
Update(ctx context.Context, name string, value any) (rowsAffected int, err error)
Updates(ctx context.Context, t T) (rowsAffected int, err error)
Count(ctx context.Context, column string) (result int64, err error)
Set(assignments ...clause.Assigner) SetUpdateOnlyInterface[T]
}
PreloadBuilder
Used in Preload callbacks with the generics API:
type PreloadBuilder interface {
Select(...string) PreloadBuilder
Omit(...string) PreloadBuilder
Where(query interface{}, args ...interface{}) PreloadBuilder
Not(query interface{}, args ...interface{}) PreloadBuilder
Or(query interface{}, args ...interface{}) PreloadBuilder
Limit(offset int) PreloadBuilder
Offset(offset int) PreloadBuilder
Order(value interface{}) PreloadBuilder
LimitPerRecord(num int) PreloadBuilder // limit per parent record (not supported for many2many)
}
G[T] requires Go 1.18 or later. The traditional *DB API continues to work in all Go versions and is not deprecated.