persistence

package
v1.23.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 12 Imported by: 35

README

Persistence(GORM)

app-starter 通过 persistence 包封装 GORM,业务侧使用 app.EnableDatabase 启用数据库,查询 API 对齐 GORM 链式风格

包结构

persistence/                 # 核心:接口、GORM 实现、连接注册(不含任何 driver 依赖)
persistence/driver/postgres/ # postgres.Config + 硬编码 gorm.io/driver/postgres
persistence/driver/mysql/    # mysql.Config + 硬编码 gorm.io/driver/mysql
persistence/driver/sqlite/   # sqlite.Config + 硬编码 glebarez/sqlite

编译隔离:只有被 import 的 driver 子包会打进二进制。persistence 核心包本身不链接任何数据库驱动。

自动注册:import driver 子包时,init() 自动 RegisterDialector,无需 RegisterDialector、无需 import gorm.io/driver/*

快速开始

import "github.com/lishimeng/app-starter/persistence/driver/postgres"

builder.EnableDatabase(setup.PostgresConfig().Build(), new(model.YourModel))

setup.go 使用 postgres.Config 构建连接(import 该子包即完成 driver 注册):

import "github.com/lishimeng/app-starter/persistence/driver/postgres"

func PostgresConfig() *postgres.Config {
    return &postgres.Config{
        UserName: os.Getenv("DB_USER"),
        Host:     os.Getenv("DB_HOST"),
        DbName:   os.Getenv("DB_DATABASE"),
        TimeZone: "Asia/Shanghai",
    }
}

环境变量示例见 examples/web-basic/setup/setup.go


连接配置

子包 Config 类型 Driver 名称
persistence/driver/postgres postgres.Config postgres
persistence/driver/mysql mysql.Config mysql
persistence/driver/sqlite sqlite.Config sqlite3

Build() 生成 persistence.BaseConfig 后传给 EnableDatabase

BaseConfig 公共字段:

字段 说明
InitDb true 时启动后执行 SyncDB(轻量级建表/补列/补索引;批量加载元数据后内存 diff)
SyncForce true 时 SyncDB 先删表再重建(会丢数据,仅开发环境使用)
SyncVerbose true 时 SyncDB 打印每一步 DDL 动作
AliasName 连接别名,默认 default
MaxIdleConns / MaxOpenConns 连接池(见下文)
Debug 是否打印 SQL(经 log 包 / slog 输出,module=gorm
DriverOpts 驱动专属选项,由 Config.Build() 自动填充

Debug=trueEnableDatabaseLog() 时,GORM SQL 经 slog 输出(module=gormtrace.*)。source=log.Config().Caller(true) 一并生效。默认忽略 record not found,慢查询阈值 200ms。

Build 内置的数据库特性

postgres.Config

字段 作用
TimeZone 追加 TimeZone=... 到 DSN
AdvancedConfig 追加 sslcert、sslkey 等额外 DSN 参数
PreferSimpleProtocol true 时禁用 pgx 隐式 prepared statement 缓存
postgres.Config{
    UserName:             "postgres",
    Host:                 "127.0.0.1",
    DbName:               "mydb",
    TimeZone:             "Asia/Shanghai",
    PreferSimpleProtocol: true,
}.Build()

mysql.Config

字段 作用
Charset 默认 utf8mb4
DisableParseTime 默认启用 parseTime=True
Loc 默认 Local
DefaultStringSize 非零/为 true 时使用 mysql.New(Config{...})
mysql.Config{
    UserName: "root",
    Host:     "127.0.0.1",
    Port:     3306,
    DbName:   "mydb",
}.Build()

各数据库连接注意事项

整理自 GORM 官方文档:连接到数据库

PostgreSQL
  • 时区:使用 postgres.Config.TimeZoneAdvancedConfig
  • prepared statement:PreferSimpleProtocol: true 可禁用 pgx 缓存
MySQL
  • 默认 DSN:charset=utf8mb4&parseTime=True&loc=Local
  • TiDB 兼容 MySQL 协议
SQLite
  • 默认纯 Go 驱动 glebarez/sqlite
  • 内存库:file::memory:?cache=shared
其他数据库

SQL Server、Oracle、ClickHouse 等可通过 persistence.RegisterDialector 在业务侧扩展,或新增 persistence/driver/xxx 子包。


SyncDB(轻量级表结构同步)

InitDb=true 时执行 SyncDB,语义对齐 Beego orm.RunSyncdb不调用 GORM AutoMigrate

实现上先批量加载库表/列/索引元数据(Postgres/MySQL 各 3 条 SQL;SQLite 2 条 + 按表 PRAGMA),在内存 diff 后仅对缺失项执行 DDL,避免逐列 Has* 查询。

操作 SyncDB
表不存在 → 创建(含主键与索引)
表已存在 → 补缺失列
表已存在 → 补缺失索引
SyncForce=true → 删表重建 是(有数据丢失风险)
SyncVerbose=true → 打印 DDL 动作
修改已有列类型/约束
删除模型中已移除的列/索引

手动调用(等价 Beego RunSyncdb):

import "github.com/lishimeng/app-starter/persistence"

err := persistence.RunSyncDB(
    persistence.DefaultAlias,
    persistence.SyncOptions{Verbose: true},
    &model.YourModel{},
)

driver Config 示例:

postgres.Config{
    InitDb:      true,
    SyncVerbose: true,
    // SyncForce: true, // 仅开发:删表重建
}.Build()

模型字段/索引从模型中删除后,数据库残留需人工处理(与 Beego 一致)。


连接池

BaseConfig.MaxIdleConns / MaxOpenConnsOpen 时设置 sqlDB.SetMaxIdleConns / SetMaxOpenConns


自定义 dialector

persistence.RegisterDialector("postgres", func(opts persistence.OpenOptions) gorm.Dialector {
    return pgdriver.New(pgdriver.Config{DSN: opts.DSN})
})

后注册会覆盖子包 init() 中的注册。常规场景使用 postgres.Config 等 Build 字段即可。


查询 API

QueryQueryCond(条件)与 QueryExec(排序/分页/执行)嵌入组成,对外仍使用 persistence.Query

条件封装(QueryCond,推荐)

减少手写 SQL 表达式,链式调用:

方法 语义
Equal(col, val) col = ?
NotEqual(col, val) col <> ?
In(col, vals) col IN ?
Like(col, s) LIKE %s%
LLike(col, s) LIKE s%(前缀)
RLike(col, s) LIKE %s(后缀)
ILike(col, s) ILIKE %s%(PostgreSQL)
EqualStr / LikeStr / ILikeStr 值为空时跳过条件
tx.Model(&model.User{}).
    Equal("status", 1).
    ILikeStr("name", keyword).
    EqualStr("code", code).
    Order("-Ctime").  // Beego 兼容:无前缀升序,"-" 前缀降序;字段名/列名均可
    Limit(10).
    Find(&list)

Order 也支持 GORM 写法("id desc")及逗号分隔("-Ctime,id")。

复杂条件仍可使用 Where("a = ? AND b > ?", x, y)

执行与分页(QueryExec)

SelectOmitOrderOffsetLimitCountFindFirstTakeUpdateUpdates

GORM 原生
tx.Model(&model.User{}).Where("status = ?", 1).Find(&list)

分页查询使用 app.SimplePager + app.QueryPage


错误处理

两条路径,不要混用判断函数
路径 你拿到的 err 该怎么判断
框架 APISession / Query / Tx 已在边界 NormalizeErr,为 persistence.ErrNotFound persistence.IsNotFound(err)
直接用 GORM*gorm.DB 等,未走本包封装) 原始 gorm.ErrRecordNotFound persistence.IsGormRecordNotFound(err)

框架 API 在 gorm_session.goquery_exec.go 出口统一调用 NormalizeErr不会gorm.ErrRecordNotFound 原样抛给业务。

persistence.ErrNotFound 是包内归一化哨兵(errors.New("persistence: not found")),供 NormalizeErr 返回、IsNotFound 比较。业务不必不应手写 errors.Is(err, persistence.ErrNotFound),统一走下方工具函数。

工具函数(persistence/errors.go
函数 只适用于
IsNotFound(err) 框架 API 返回的 err(已归一化)
IsGormRecordNotFound(err) 直接 GORM 返回的原始 err
IsNotFoundAny(err) 来源不确定、或需同时兼容两种 err 时
IsDuplicate(err) 任意来源的唯一约束类错误(字符串启发式)
示例

走框架(推荐):

err := session.First(&row)
if persistence.IsNotFound(err) {
    // 记录不存在
}

直接用 GORM(少数场景):

err := db.First(&row).Error
if persistence.IsGormRecordNotFound(err) {
    // 记录不存在
}

业务不要 import "gorm.io/gorm" 判断 ErrRecordNotFound;走框架用 IsNotFound,直连 GORM 用 IsGormRecordNotFound

First / Take / Find 等经框架封装后,无匹配时 persistence.IsNotFound(err)true


参考链接

Documentation

Index

Constants

View Source
const DefaultAlias = "default"

Variables

View Source
var (
	DriverMysql    = Driver{"mysql"}
	DriverSqlite   = Driver{"sqlite3"}
	DriverOracle   = Driver{"oracle"}
	DriverPostgres = Driver{"postgres"}
	DriverTiDB     = Driver{"tidb"}
)
View Source
var ErrNotFound = errNotFound

ErrNotFound is returned by framework APIs after NormalizeErr (not gorm.ErrRecordNotFound).

Functions

func CheckErr

func CheckErr(err error) error

func GormDB added in v1.22.1

func GormDB(q Query) (*gormdb.DB, bool)

GormDB exposes the underlying *gorm.DB for a Query.

func InitDatabase

func InitDatabase(config BaseConfig) (err error)

func InitOrm

func InitOrm(config BaseConfig) (err error)

func Install added in v1.22.1

func Install() error

Install registers the GORM connector.

func IsDuplicate added in v1.22.7

func IsDuplicate(err error) bool

IsDuplicate reports common unique-constraint violations.

func IsGormRecordNotFound added in v1.22.8

func IsGormRecordNotFound(err error) bool

IsGormRecordNotFound reports raw GORM missing-record errors. Use for direct gorm.DB calls only.

func IsNotFound added in v1.22.7

func IsNotFound(err error) bool

IsNotFound reports normalized not-found errors from Session / Query / Tx.

func IsNotFoundAny added in v1.22.8

func IsNotFoundAny(err error) bool

IsNotFoundAny reports not-found when err source is unknown or mixed.

func NormalizeErr added in v1.22.7

func NormalizeErr(err error) error

NormalizeErr maps gorm driver errors to persistence-level errors.

func Ping added in v1.23.2

func Ping(alias string) error

Ping checks database connectivity for alias. No-op when the alias is not configured.

func RegisterDataBase

func RegisterDataBase(init bool, aliasName, driverName, dataSource string, _ ...any) (err error)

func RegisterDatabase

func RegisterDatabase(config BaseConfig) (err error)

func RegisterDialector added in v1.22.1

func RegisterDialector(driver string, opener DialectorOpener)

RegisterDialector registers a dialector for a driver name. Built-in configs register their driver automatically; use this only for custom drivers.

func RegisterModels

func RegisterModels(models ...any)

func RegisterSession added in v1.22.1

func RegisterSession(alias string, session Session)

RegisterSession stores a session for the given alias.

func RunSyncDB added in v1.22.2

func RunSyncDB(alias string, opts SyncOptions, models ...any) error

RunSyncDB runs SyncDB on a registered database alias (Beego orm.RunSyncdb equivalent).

func SessionDB added in v1.22.1

func SessionDB(ctx *OrmContext) (*gormdb.DB, bool)

SessionDB returns the underlying *gorm.DB for an OrmContext.

func SetConnector added in v1.22.1

func SetConnector(c Connector)

SetConnector installs the active database connector. Called from Install().

func SetDebug added in v1.22.1

func SetDebug(enable bool)

SetDebug enables or disables SQL debug logging for all active sessions and the global debug switch when supported.

func SetFallbackSessionFactory added in v1.22.1

func SetFallbackSessionFactory(factory func(alias string) Session)

SetFallbackSessionFactory provides sessions when no alias has been registered yet.

func SetGlobalDebugSetter added in v1.22.1

func SetGlobalDebugSetter(fn func(bool))

SetGlobalDebugSetter registers a global debug toggle.

func SyncDB added in v1.22.2

func SyncDB(db *gormdb.DB, opts SyncOptions, models ...any) error

SyncDB creates missing tables, adds missing columns and indexes. It does not alter or drop existing columns or indexes. Catalog metadata is loaded in batch; Migrator Has* is not used for diff.

func TxDB added in v1.22.1

func TxDB(ctx TxContext) (*gormdb.DB, bool)

TxDB returns the underlying transactional *gorm.DB.

Types

type BaseConfig

type BaseConfig struct {
	InitDb       bool
	SyncForce    bool
	SyncVerbose  bool
	AliasName    string
	Driver       Driver
	DataSource   string
	MaxIdleConns int
	MaxOpenConns int
	Debug        bool
	Models       []any
	DriverOpts   any // 驱动专属选项,由对应 *Config.Build 填充
}

BaseConfig 数据库连接配置,由 PostgresConfig / MysqlConfig 等 Build 生成。

func (*BaseConfig) DebugLog added in v1.22.1

func (b *BaseConfig) DebugLog(enable bool)

func (*BaseConfig) MaxConn

func (b *BaseConfig) MaxConn(n int)

func (*BaseConfig) MaxIdle

func (b *BaseConfig) MaxIdle(n int)

func (*BaseConfig) RegisterModel

func (b *BaseConfig) RegisterModel(models ...any)

type Connector added in v1.22.1

type Connector interface {
	Open(opts OpenOptions) (Session, error)
	Migrate(alias string, opts SyncOptions, models ...any) error
	RegisterModels(models ...any)
}

Connector opens database sessions.

type DialectorOpener added in v1.22.1

type DialectorOpener func(opts OpenOptions) gormdb.Dialector

DialectorOpener builds a GORM dialector from OpenOptions. Built-in drivers (postgres, mysql, sqlite) register automatically via *Config init.

type Driver

type Driver struct {
	Name string
}

type OpenOptions added in v1.22.1

type OpenOptions struct {
	Alias      string
	MaxIdle    int
	MaxOpen    int
	Debug      bool
	InitDB     bool
	Driver     string
	DSN        string
	DriverOpts any // driver-specific options set by *Config.Build()
}

OpenOptions carries connection-level settings for a Connector.

type OrmContext

type OrmContext struct {
	// contains filtered or unexported fields
}

func New

func New() *OrmContext

func NewOrm

func NewOrm(aliasName string) *OrmContext

func WrapSession added in v1.22.1

func WrapSession(s Session) *OrmContext

func (*OrmContext) Model added in v1.22.1

func (o *OrmContext) Model(value interface{}) Query

func (*OrmContext) SetLogEnable added in v1.12.6

func (o *OrmContext) SetLogEnable(enable bool)

func (*OrmContext) Transaction

func (o *OrmContext) Transaction(h func(TxContext) error) (err error)

type Pager

type Pager struct {
	PageNo     int // start with 1
	PageSize   int // > 0
	TotalPage  int
	TotalCount int
}

func BuildPager

func BuildPager(pageNo int, pageSize int) Pager

func (*Pager) GetLimit

func (p *Pager) GetLimit() (limit int, start int)

func (*Pager) IsFirstPage

func (p *Pager) IsFirstPage() bool

func (*Pager) IsLastPage

func (p *Pager) IsLastPage() bool

func (*Pager) Next

func (p *Pager) Next()

func (*Pager) SetPageNo

func (p *Pager) SetPageNo(no int)

func (*Pager) SetTotal

func (p *Pager) SetTotal(total int)

type Query added in v1.22.1

type Query interface {
	QueryCond
	QueryExec
}

Query 由 QueryCond 与 QueryExec 组成,对外链式用法不变。

通过 Session.Model 或 Tx.Model 获得:

q := tx.Model(&User{})          // 指定表/模型
q = q.Equal("id", 1)            // 条件
err := q.First(&row)            // 执行

SQL:

SELECT * FROM users WHERE id = 1 ORDER BY users.id ASC LIMIT 1

或一步写完:

err := tx.Model(&User{}).Equal("id", 1).First(&row)

type QueryCond added in v1.22.1

type QueryCond interface {
	// Equal 追加 column = ? 条件。
	//
	// 例:tx.Model(&User{}).Equal("id", 1).First(&row)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE id = 1 ORDER BY users.id ASC LIMIT 1
	Equal(column string, value any) Query

	// NotEqual 追加 column <> ? 条件。
	//
	// 例:tx.Model(&User{}).NotEqual("status", 0).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE status <> 0
	NotEqual(column string, value any) Query

	// In 追加 column IN ? 条件;values 为 slice 或数组。
	//
	// 例:tx.Model(&User{}).In("id", []int{1, 2, 3}).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE id IN (1, 2, 3)
	In(column string, values any) Query

	// Like 追加 column LIKE %value%(两端模糊匹配)。
	//
	// 例:tx.Model(&User{}).Like("name", "张").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE name LIKE '%张%'
	Like(column string, value string) Query

	// LLike 追加 column LIKE value%(前缀匹配)。
	//
	// 例:tx.Model(&User{}).LLike("code", "A").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE code LIKE 'A%'
	LLike(column string, value string) Query

	// RLike 追加 column LIKE %value(后缀匹配)。
	//
	// 例:tx.Model(&User{}).RLike("email", "@test.com").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE email LIKE '%@test.com'
	RLike(column string, value string) Query

	// ILike 追加 column ILIKE %value%(不区分大小写,PostgreSQL)。
	//
	// 例:tx.Model(&User{}).ILike("name", "abc").Find(&rows)
	//
	// SQL(PostgreSQL):
	//
	//	SELECT * FROM users WHERE name ILIKE '%abc%'
	ILike(column string, value string) Query

	// EqualStr 当 value 非空时追加 Equal,空字符串跳过该条件(便于接 URL 查询参数)。
	//
	// 例:tx.Model(&User{}).EqualStr("code", "c1").EqualStr("conn_type", "").Find(&rows)
	//
	// SQL(conn_type 为空,该条件不出现):
	//
	//	SELECT * FROM users WHERE code = 'c1'
	EqualStr(column string, value string) Query

	// LikeStr 当 value 非空时追加 Like,空字符串跳过。
	//
	// 例:tx.Model(&User{}).LikeStr("name", "张").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE name LIKE '%张%'
	LikeStr(column string, value string) Query

	// LLikeStr 当 value 非空时追加 LLike,空字符串跳过。
	//
	// 例:tx.Model(&User{}).LLikeStr("code", "A").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE code LIKE 'A%'
	LLikeStr(column string, value string) Query

	// RLikeStr 当 value 非空时追加 RLike,空字符串跳过。
	//
	// 例:tx.Model(&User{}).RLikeStr("email", "@test.com").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE email LIKE '%@test.com'
	RLikeStr(column string, value string) Query

	// ILikeStr 当 value 非空时追加 ILike,空字符串跳过。
	//
	// 例:tx.Model(&User{}).ILikeStr("name", "abc").Find(&rows)
	//
	// SQL(PostgreSQL):
	//
	//	SELECT * FROM users WHERE name ILIKE '%abc%'
	ILikeStr(column string, value string) Query

	// Where 追加原生 GORM 条件,query 可为 SQL 片段或 map。
	//
	// 例:tx.Model(&User{}).Where("age > ?", 18).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE age > 18
	//
	// 例:tx.Model(&User{}).Where(map[string]any{"status": 1}).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE status = 1
	Where(query interface{}, args ...interface{}) Query

	// Or 追加 OR 条件,与前面条件为或关系。
	//
	// 例:tx.Model(&User{}).Equal("status", 1).Or("status = ?", 2).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE status = 1 OR status = 2
	Or(query interface{}, args ...interface{}) Query

	// Not 对条件取反(NOT)。
	//
	// 例:tx.Model(&User{}).Not("status = ?", 0).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE NOT (status = 0)
	Not(query interface{}, args ...interface{}) Query
}

QueryCond 查询条件构建。所有方法均返回 Query,可链式调用。

column 参数使用数据库列名(如 "conn_type"),与 gorm tag 中 column 一致。 下文 SQL 以表名 users、列名与示例参数为例;实际表名由 Model 的 TableName/gorm 命名决定。

典型用法:

tx.Model(&User{}).
    EqualStr("code", "c1").
    ILikeStr("name", "abc").
    Equal("enabled", 1).Find(&rows)

SQL:

SELECT * FROM users
WHERE code = 'c1' AND name ILIKE '%abc%' AND enabled = 1

type QueryExec added in v1.22.1

type QueryExec interface {
	// Select 指定参与本次操作的列,行为取决于后续链式方法:
	//
	//   - 接 Find/First/Take:只查询列出的字段(列名或 struct 字段名)。
	//   - 接 Updates:只更新列出的字段(白名单),不是先 SELECT 再 UPDATE。
	//
	// 例(只查部分列):
	//
	//	tx.Model(&User{}).Select("id", "name").Find(&rows)
	//
	// SQL:
	//
	//	SELECT id, name FROM users
	//
	// 例(只更新 status;row.Id = 5, row.Status = 3):
	//
	//	tx.Model(&row).Select("Status").Updates(&row)
	//
	// SQL:
	//
	//	UPDATE users SET status = 3 WHERE id = 5
	Select(query interface{}, args ...interface{}) Query

	// Omit 指定本次操作忽略的列(黑名单),可接 Updates / Find 等。
	//
	// 例(更新除 name 外的非零字段;row.Id = 5, row.Status = 2, row.Name = "x"):
	//
	//	tx.Model(&row).Omit("Name").Updates(&row)
	//
	// SQL:
	//
	//	UPDATE users SET status = 2 WHERE id = 5
	//
	// 例(查询时排除大字段):
	//
	//	tx.Model(&User{}).Omit("config").Find(&rows)
	//
	// SQL:
	//
	//	SELECT id, name, code, ... /* 不含 config */ FROM users
	Omit(columns ...string) Query

	// Order 追加排序,可多次调用或传入逗号分隔表达式。
	// Beego 兼容:"id"→升序,"-Ctime"→降序;也支持 GORM 写法 "id desc"。
	//
	// 例:tx.Model(&User{}).Order("-Ctime").Order("id").Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users ORDER BY id DESC, name ASC
	Order(value interface{}) Query

	// Offset 跳过前 n 条记录(分页)。
	//
	// 例:tx.Model(&User{}).Offset(20).Limit(10).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users LIMIT 10 OFFSET 20
	Offset(offset int) Query

	// Limit 限制返回条数。
	//
	// 例:tx.Model(&User{}).Limit(5).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users LIMIT 5
	Limit(limit int) Query

	// Count 统计当前条件下记录数,不加载行数据。
	//
	// 例:n, err := tx.Model(&User{}).Equal("enabled", 1).Count()
	//
	// SQL:
	//
	//	SELECT count(*) FROM users WHERE enabled = 1
	Count() (int64, error)

	// Find 查询多条,结果写入 dest(通常为 *[]Model)。
	// 无匹配记录时返回 nil,dest 为空 slice,不报错。
	//
	// conds 可选:额外追加 Where 条件,一般通过链式 Equal/Where 已足够。
	//
	// 例:
	//
	//	tx.Model(&User{}).Equal("enabled", 1).Find(&rows)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE enabled = 1
	Find(dest interface{}, conds ...interface{}) error

	// First 查询符合条件的第一条记录,写入 dest(通常为 *Model)。
	//
	// 按主键或 Order 决定“第一条”;无匹配时返回 gorm.ErrRecordNotFound。
	// 与 Take 的区别:First 在无 Order 时倾向按主键升序取第一条。
	//
	// 例:
	//
	//	tx.Model(&User{}).Equal("id", 1).First(&row)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE id = 1 ORDER BY users.id ASC LIMIT 1
	First(dest interface{}, conds ...interface{}) error

	// Take 取一条记录,无匹配时返回 gorm.ErrRecordNotFound。
	// 与 First 类似,但不保证排序语义,任意匹配一行即可。
	//
	// 例:
	//
	//	tx.Model(&User{}).Equal("code", "c1").Take(&row)
	//
	// SQL:
	//
	//	SELECT * FROM users WHERE code = 'c1' LIMIT 1
	Take(dest interface{}, conds ...interface{}) error

	// Updates 按当前 Model/条件更新记录。
	//
	// 传入 struct 时:
	//   - 不更新主键;
	//   - 默认跳过零值字段(0、""、false、nil 指针等);
	//   - 若需只更新部分字段,先链式 Select 指定列(白名单)。
	//
	// 传入 map[string]any 时:只更新 map 中的键,零值也会写入。
	//
	// 注意:若 row 由 First 加载且未 Select/Omit,Updates(&row) 会尝试更新
	// struct 中所有非零字段;仅改一列时可 Update、Select 或传 map。
	//
	// 例(只更新 status;row.Id = 5, row.Status = 2):
	//
	//	tx.Model(&row).Select("Status").Updates(&row)
	//
	// SQL:
	//
	//	UPDATE users SET status = 2 WHERE id = 5
	//
	// 例(map 更新,含零值):
	//
	//	tx.Model(&User{}).Equal("id", 1).Updates(map[string]any{"enabled": 0})
	//
	// SQL:
	//
	//	UPDATE users SET enabled = 0 WHERE id = 1
	Updates(value interface{}) error

	// Update 更新单列,column 为列名或 struct 字段名,value 为新值。
	// 零值也会写入(与 Updates(struct) 不同)。
	//
	// 例(status 自增后写回;row.Id = 5, row.Status = 3):
	//
	//	tx.Model(&row).Update("status", row.Status)
	//
	// SQL:
	//
	//	UPDATE users SET status = 3 WHERE id = 5
	//
	// 例(按条件更新):
	//
	//	tx.Model(&User{}).Equal("id", 1).Update("enabled", 0)
	//
	// SQL:
	//
	//	UPDATE users SET enabled = 0 WHERE id = 1
	Update(column string, value any) error
}

QueryExec 排序、分页、查询执行与更新。

读操作:Count / Find / First / Take。 写操作:Update / Updates / Omit(配合 Updates 或读操作)。

典型用法:

var rows []User
err := tx.Model(&User{}).Equal("enabled", 1).
    Order("id desc").Offset(10).Limit(10).Find(&rows)

SQL:

SELECT * FROM users
WHERE enabled = 1
ORDER BY id DESC
LIMIT 10 OFFSET 10

type Session added in v1.22.1

type Session interface {
	Transaction(fn func(Tx) error) error
	Model(value interface{}) Query
	SetDebug(enable bool)
	Alias() string
}

Session is the unit of work for database access, typically one per alias.

func GetSession added in v1.22.1

func GetSession(alias string) Session

GetSession returns the session registered for alias, or nil.

type SyncOptions added in v1.22.2

type SyncOptions struct {
	Force   bool // drop and recreate tables before sync (data loss)
	Verbose bool // log each DDL action
}

SyncOptions controls lightweight schema sync (Beego RunSyncdb semantics).

type Tx added in v1.22.1

type Tx interface {
	Model(value interface{}) Query
	Create(value interface{}) error
	Save(value interface{}) error
	Delete(value interface{}, conds ...interface{}) error
	First(dest interface{}, conds ...interface{}) error
	Raw(sql string, values ...interface{}) Query
}

Tx represents a transactional database session.

type TxContext

type TxContext struct {
	Tx Tx
}

func WrapTx added in v1.22.1

func WrapTx(tx Tx) TxContext

func (*TxContext) Create added in v1.22.1

func (t *TxContext) Create(value interface{}) error

func (*TxContext) Delete added in v1.22.1

func (t *TxContext) Delete(value interface{}, conds ...interface{}) error

func (*TxContext) First added in v1.22.1

func (t *TxContext) First(dest interface{}, conds ...interface{}) error

func (*TxContext) Model added in v1.22.1

func (t *TxContext) Model(value interface{}) Query

func (*TxContext) Raw added in v1.22.1

func (t *TxContext) Raw(sql string, values ...interface{}) Query

func (*TxContext) Save added in v1.22.1

func (t *TxContext) Save(value interface{}) error

Directories

Path Synopsis
driver
mysql
Package mysql provides MysqlConfig and registers the GORM mysql dialector on import.
Package mysql provides MysqlConfig and registers the GORM mysql dialector on import.
postgres
Package postgres provides PostgresConfig and registers the GORM postgres dialector on import.
Package postgres provides PostgresConfig and registers the GORM postgres dialector on import.
sqlite
Package sqlite provides SqliteConfig and registers the GORM sqlite dialector on import.
Package sqlite provides SqliteConfig and registers the GORM sqlite dialector on import.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL