- 实现配置文件自动查找功能,支持yaml、yml、toml、ini、json格式 - 添加查询缓存机制,提高重复查询性能 - 新增构建脚本build.sh和build.bat用于跨平台编译 - 添加完整的数据库连接配置和时间字段配置功能 - 实现DAO基类提供通用CRUD操作方法 - 添加配置文件示例和相关测试用例 |
||
|---|---|---|
| .. | ||
| cmd/gendb | ||
| config | ||
| core | ||
| driver | ||
| generator | ||
| introspector | ||
| tracing | ||
| utils | ||
| README.md | ||
| VALIDATION.md | ||
| config.example.yaml | ||
| config.yaml | ||
| config_time_test.go | ||
| core_test.go | ||
| features_test.go | ||
| gendb.bat | ||
| gendb.exe | ||
| go.mod | ||
| go.sum | ||
| main_test.go | ||
| perf_report.go | ||
| read_time_test.go | ||
| time_test.go | ||
| validation_test.go | ||
README.md
Magic-ORM 自主 ORM 框架架构文档
📋 目录
概述
Magic-ORM 是一个完全自主研发的企业级 Go 语言 ORM 框架,不依赖任何第三方 ORM 库。框架基于 database/sql 标准库构建,提供了全自动化事务管理、面向接口设计、智能字段映射等高级特性。支持 MySQL、SQLite 等主流数据库,内置完整的迁移管理和可观测性支持,帮助开发者快速构建高质量的数据访问层。
设计理念:
- 零依赖:仅依赖 Go 标准库
database/sql - 高性能:优化的查询执行器和连接池管理
- 易用性:简洁的 API 设计和智能默认行为
- 可扩展:面向接口的设计,支持自定义驱动扩展
- 内置驱动:框架自带所有主流数据库驱动,无需额外安装
核心特性
- 全自动化嵌套事务支持:无需手动管理事务传播行为
- 面向接口化设计:核心功能均通过接口暴露,便于 Mock 与扩展
- 内置主流数据库驱动:开箱即用,并支持自定义驱动扩展
- 统一配置组件:与框架配置体系无缝集成
- 单例模式数据库对象:同一分组配置仅初始化一次
- 双模式操作:原生 SQL + ORM 链式操作
- OpenTelemetry 可观测性:完整支持 Tracing、Logging、Metrics
- 智能结果映射:
Scan自动识别 Map/Struct/Slice,无需sql.ErrNoRows判空 - 全自动字段映射:无需结构体标签,自动匹配数据库字段
- 参数智能过滤:自动识别并过滤无效/空值字段
- Model/DAO 代码生成器:一键生成全量数据访问代码
- 高级特性:调试模式、DryRun、自定义 Handler、软删除、时间自动更新、模型关联、主从集群等
- 自动化数据库迁移:支持自动迁移、增量迁移、回滚迁移等完整迁移管理
架构设计
整体架构图
graph TB
A[应用层] --> B[Magic-ORM 框架]
B --> C[配置中心]
B --> D[数据库连接池]
B --> E[事务管理器]
B --> F[迁移管理器]
C --> C1[统一配置组件]
C --> C2[环境配置]
D --> D1[MySQL 驱动]
D --> D2[SQLite 驱动]
D --> D3[自定义驱动]
E --> E1[自动嵌套事务]
E --> E2[事务传播控制]
F --> F1[自动迁移]
F --> F2[增量迁移]
F --> F3[回滚迁移]
B --> G[观测性组件]
G --> G1[Tracing]
G --> G2[Logging]
G --> G3[Metrics]
B --> H[工具组件]
H --> H1[字段映射器]
H --> H2[参数过滤器]
H --> H3[结果映射器]
H --> H4[代码生成器]
目录结构
magic-orm/
├── core/ # 核心实现
│ ├── database.go # 数据库连接管理
│ ├── transaction.go # 事务管理
│ ├── query.go # 查询构建器
│ └── mapper.go # 字段映射器
├── migrate/ # 迁移管理
│ └── migrator.go # 自动迁移实现
├── generator/ # 代码生成器
│ ├── model.go # Model 生成
│ └── dao.go # DAO 生成
├── tracing/ # OpenTelemetry 集成
│ └── tracer.go # 链路追踪
└── driver/ # 数据库驱动适配(已内置)
├── mysql.go # MySQL 驱动(内置)
├── sqlite.go # SQLite 驱动(内置)
├── postgres.go # PostgreSQL 驱动(内置)
├── sqlserver.go # SQL Server 驱动(内置)
├── oracle.go # Oracle 驱动(内置)
└── clickhouse.go # ClickHouse 驱动(内置)
核心组件说明
1. 数据库连接管理 (core/database.go)
- 单例模式:全局唯一的
DB实例,确保资源高效利用 - 多数据库支持:支持 MySQL、SQLite、PostgreSQL、SQL Server、Oracle、ClickHouse 等
- 驱动内置:所有主流数据库驱动已预装在框架中
- 连接池优化:内置 sql.DB 连接池管理
- 健康检查:启动时自动执行
Ping()验证连接
核心配置项:
Config{
DriverName: "mysql", // 驱动名称
DataSource: "dns", // 数据源连接字符串
MaxIdleConns: 10, // 最大空闲连接数
MaxOpenConns: 100, // 最大打开连接数
Debug: true, // 调试模式
}
2. 查询构建器 (core/query.go)
提供流畅的链式查询接口:
- 条件查询: Where, Or, And
- 字段选择: Select, Omit
- 排序分页: Order, Limit, Offset
- 分组统计: Group, Having, Count
- 连接查询: Join, LeftJoin, RightJoin
- 预加载: Preload
示例:
var users []model.User
db.Model(&model.User{}).
Where("status = ?", 1).
Select("id", "username").
Order("id DESC").
Limit(10).
Find(&users)
3. 事务管理器 (core/transaction.go)
提供完整的事务管理能力:
- 自动嵌套事务: 自动管理事务传播
- 保存点支持: 支持部分回滚
- 生命周期回调: Before/After 钩子
4. 字段映射器 (core/mapper.go)
智能字段映射系统:
- 驼峰转下划线: UserName -> user_name
- 标签解析: 支持 db, json 标签
- 类型转换: Go 类型与数据库类型自动转换
- 零值过滤: 自动过滤空值和零值
5. 迁移管理 (migrate/migrator.go)
完整的数据库迁移方案:
- 自动迁移: 根据模型自动创建/修改表结构
- 增量迁移: 支持添加字段、索引等
- 回滚支持: 支持迁移回滚
- 版本管理: 迁移版本记录和管理
6. 驱动管理器 (driver/manager.go)
统一的驱动管理和注册中心:
- 驱动注册: 自动注册所有内置驱动
- 驱动选择: 根据配置自动选择合适的驱动
- 驱动扩展: 支持用户自定义驱动注册
- 版本检测: 自动检测数据库版本并适配特性
// 驱动管理器会自动处理
var supportedDrivers = map[string]driver.Driver{
"mysql": &MySQLDriver{},
"sqlite": &SQLiteDriver{},
"postgres": &PostgresDriver{},
"sqlserver": &SQLServerDriver{},
"oracle": &OracleDriver{},
"clickhouse": &ClickHouseDriver{},
}
技术栈
核心依赖
| 组件 | 版本 | 说明 |
|---|---|---|
| Go | 1.25+ | 编程语言 |
| database/sql | stdlib | Go 标准库 |
| driver-go | Latest | 数据库驱动接口规范 |
| OpenTelemetry | Latest | 可观测性框架 |
| 内置驱动集合 | Latest | 包含所有主流数据库驱动 |
支持的数据库驱动
框架已内置以下数据库驱动,无需额外安装:
- MySQL: 内置驱动(基于
github.com/go-sql-driver/mysql) - SQLite: 内置驱动(基于
github.com/mattn/go-sqlite3) - PostgreSQL: 内置驱动(基于
github.com/lib/pq) - SQL Server: 内置驱动(基于
github.com/denisenkom/go-mssqldb) - Oracle: 内置驱动(基于
github.com/godror/godror) - ClickHouse: 内置驱动(基于
github.com/ClickHouse/clickhouse-go) - 自定义驱动: 实现
driver.Driver接口即可扩展
💡 说明:框架在编译时已将所有主流数据库驱动打包,用户只需引入
magic-orm即可完成所有数据库操作,无需单独安装各数据库驱动。
核心接口设计
1. 数据库连接接口
// IDatabase 数据库连接接口
type IDatabase interface {
// 基础操作
DB() *sql.DB
Close() error
Ping() error
// 事务管理
Begin() (ITx, error)
Transaction(fn func(ITx) error) error
// 查询构建器
Model(model interface{}) IQuery
Table(name string) IQuery
Query(result interface{}, query string, args ...interface{}) error
Exec(query string, args ...interface{}) (sql.Result, error)
// 迁移管理
Migrate(models ...interface{}) error
// 配置
SetDebug(bool)
SetMaxIdleConns(int)
SetMaxOpenConns(int)
SetConnMaxLifetime(time.Duration)
}
2. 事务接口
// ITx 事务接口
type ITx interface {
// 基础操作
Commit() error
Rollback() error
// 查询操作
Model(model interface{}) IQuery
Table(name string) IQuery
Insert(model interface{}) (int64, error)
BatchInsert(models interface{}, batchSize int) error
Update(model interface{}, data map[string]interface{}) error
Delete(model interface{}) error
// 原生 SQL
Query(result interface{}, query string, args ...interface{}) error
Exec(query string, args ...interface{}) (sql.Result, error)
}
3. 查询构建器接口
// IQuery 查询构建器接口
type IQuery interface {
// 条件查询
Where(query string, args ...interface{}) IQuery
Or(query string, args ...interface{}) IQuery
And(query string, args ...interface{}) IQuery
// 字段选择
Select(fields ...string) IQuery
Omit(fields ...string) IQuery
// 排序
Order(order string) IQuery
OrderBy(field string, direction string) IQuery
// 分页
Limit(limit int) IQuery
Offset(offset int) IQuery
Page(page, pageSize int) IQuery
// 分组
Group(group string) IQuery
Having(having string, args ...interface{}) IQuery
// 连接
Join(join string, args ...interface{}) IQuery
LeftJoin(table, on string) IQuery
RightJoin(table, on string) IQuery
InnerJoin(table, on string) IQuery
// 预加载
Preload(relation string, conditions ...interface{}) IQuery
// 执行查询
First(result interface{}) error
Find(result interface{}) error
Count(count *int64) IQuery
Exists() (bool, error)
// 更新和删除
Updates(data interface{}) error
UpdateColumn(column string, value interface{}) error
Delete() error
// 特殊模式
Unscoped() IQuery
DryRun() IQuery
Debug() IQuery
// 构建 SQL(不执行)
Build() (string, []interface{})
}
4. 模型接口
// IModel 模型接口
type IModel interface {
// 表名映射
TableName() string
// 生命周期回调(可选)
BeforeCreate(tx ITx) error
AfterCreate(tx ITx) error
BeforeUpdate(tx ITx) error
AfterUpdate(tx ITx) error
BeforeDelete(tx ITx) error
AfterDelete(tx ITx) error
BeforeSave(tx ITx) error
AfterSave(tx ITx) error
}
5. 字段映射器接口
// IFieldMapper 字段映射器接口
type IFieldMapper interface {
// 结构体字段转数据库列
StructToColumns(model interface{}) (map[string]interface{}, error)
// 数据库列转结构体字段
ColumnsToStruct(row *sql.Rows, model interface{}) error
// 获取表名
GetTableName(model interface{}) string
// 获取主键字段
GetPrimaryKey(model interface{}) string
// 获取字段信息
GetFields(model interface{}) []FieldInfo
}
// FieldInfo 字段信息
type FieldInfo struct {
Name string // 字段名
Column string // 列名
Type string // Go 类型
DbType string // 数据库类型
Tag string // 标签
IsPrimary bool // 是否主键
IsAuto bool // 是否自增
}
6. 迁移管理器接口
// IMigrator 迁移管理器接口
type IMigrator interface {
// 自动迁移
AutoMigrate(models ...interface{}) error
// 表操作
CreateTable(model interface{}) error
DropTable(model interface{}) error
HasTable(model interface{}) (bool, error)
RenameTable(oldName, newName string) error
// 列操作
AddColumn(model interface{}, field string) error
DropColumn(model interface{}, field string) error
HasColumn(model interface{}, field string) (bool, error)
RenameColumn(model interface{}, oldField, newField string) error
// 索引操作
CreateIndex(model interface{}, field string) error
DropIndex(model interface{}, field string) error
HasIndex(model interface{}, field string) (bool, error)
}
7. 代码生成器接口
// ICodeGenerator 代码生成器接口
type ICodeGenerator interface {
// 生成 Model 代码
GenerateModel(table string, outputDir string) error
// 生成 DAO 代码
GenerateDAO(table string, outputDir string) error
// 生成完整代码
GenerateAll(tables []string, outputDir string) error
// 从数据库读取表结构
InspectTable(tableName string) (*TableSchema, error)
}
// TableSchema 表结构信息
type TableSchema struct {
Name string
Columns []ColumnInfo
Indexes []IndexInfo
}
8. 配置结构
// Config 数据库配置
type Config struct {
DriverName string // 驱动名称
DataSource string // 数据源连接字符串
MaxIdleConns int // 最大空闲连接数
MaxOpenConns int // 最大打开连接数
ConnMaxLifetime time.Duration // 连接最大生命周期
Debug bool // 调试模式
// 主从配置
Replicas []string // 从库列表
ReadPolicy ReadPolicy // 读负载均衡策略
// OpenTelemetry
EnableTracing bool
ServiceName string
}
// ReadPolicy 读负载均衡策略
type ReadPolicy int
const (
Random ReadPolicy = iota
RoundRobin
LeastConn
)
快速开始
1. 安装 Magic-ORM
# 仅需安装 magic-orm,所有数据库驱动已内置
go get github.com/your-org/magic-orm
✅ 无需单独安装数据库驱动! 所有驱动已包含在 magic-orm 中。
2. 配置数据库
在配置文件中设置数据库参数:
database:
type: mysql # 或 sqlite, postgres
dns: "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
debug: true
max_idle_conns: 10
max_open_conns: 100
3. 定义模型
package model
import "time"
type User struct {
ID int64 `json:"id" db:"id"`
Username string `json:"username" db:"username"`
Password string `json:"-" db:"password"`
Email string `json:"email" db:"email"`
Status int `json:"status" db:"status"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
// 表名映射
func (User) TableName() string {
return "user"
}
4. 初始化数据库连接
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"your-project/orm"
)
func main() {
// 初始化数据库连接
db, err := orm.NewDatabase(&orm.Config{
DriverName: "mysql",
DataSource: "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local",
MaxIdleConns: 10,
MaxOpenConns: 100,
Debug: true,
})
if err != nil {
panic(err)
}
defer db.Close()
// 执行迁移
orm.Migrate(db, &model.User{})
}
5. CRUD 操作
// 创建
user := &model.User{Username: "admin", Password: "123456", Email: "admin@example.com"}
id, err := db.Insert(user)
// 查询单个
var user model.User
err := db.Model(&model.User{}).Where("id = ?", 1).First(&user)
// 查询多个
var users []model.User
err := db.Model(&model.User{}).Where("status = ?", 1).Order("id DESC").Find(&users)
// 更新
err := db.Model(&model.User{}).Where("id = ?", 1).Updates(map[string]interface{}{
"email": "new@example.com",
})
// 删除
err := db.Model(&model.User{}).Where("id = ?", 1).Delete()
// 原生 SQL
var results []model.User
err := db.Query(&results, "SELECT * FROM user WHERE status = ?", 1)
6. 事务操作
// 自动嵌套事务
err := db.Transaction(func(tx *orm.Tx) error {
// 创建用户
user := &model.User{Username: "test", Email: "test@example.com"}
_, err := tx.Insert(user)
if err != nil {
return err
}
// 创建关联数据(自动加入同一事务)
profile := &model.Profile{UserID: user.ID, Avatar: "default.png"}
_, err = tx.Insert(profile)
if err != nil {
return err
}
return nil
})
详细功能说明
1. 全自动化嵌套事务
框架自动管理事务的传播行为,支持以下场景:
- REQUIRED: 如果当前存在事务,则加入该事务;否则创建新事务
- REQUIRES_NEW: 无论当前是否存在事务,都创建新事务
- NESTED: 在当前事务中创建嵌套事务(使用保存点)
示例:
// 外层事务
db.Transaction(func(tx *orm.Tx) error {
// 内层自动加入同一事务
userService.CreateUser(tx, user)
orderService.CreateOrder(tx, order)
return nil
})
2. 智能结果映射
无需手动处理 sql.ErrNoRows,框架自动识别返回类型:
// 自动识别 Struct
var user model.User
db.Model(&model.User{}).Where("id = ?", 1).First(&user) // 不存在时返回零值,不报错
// 自动识别 Slice
var users []model.User
db.Model(&model.User{}).Where("status = ?", 1).Find(&users) // 空结果返回空切片,而非 nil
// 自动识别 Map
var result map[string]interface{}
db.Table("user").Where("id = ?", 1).First(&result)
3. 全自动字段映射
无需结构体标签,框架自动匹配字段:
// 驼峰命名自动转下划线
type UserInfo struct {
UserName string // 自动映射到 user_name 字段
UserAge int // 自动映射到 user_age 字段
CreatedAt string // 自动映射到 created_at 字段
}
4. 参数智能过滤
自动过滤零值和空指针:
// 仅更新非零值字段
updateData := &model.User{
Username: "newname", // 会被更新
Email: "", // 空值,自动过滤
Status: 0, // 零值,自动过滤
}
db.Model(&user).Updates(updateData)
5. OpenTelemetry 可观测性
完整支持分布式追踪:
// 自动注入 Span
ctx, span := otel.Tracer("gin-base").Start(context.Background(), "DB Query")
defer span.End()
// 自动记录 SQL 执行时间、错误信息等
db.WithContext(ctx).Find(&users)
6. 数据库迁移管理
自动迁移
database.SetAutoMigrate(&model.User{}, &model.Order{})
增量迁移
// 添加新字段
type UserV2 struct {
model.User
Phone string ` + "`" + `json:"phone" gorm:"column:phone;type:varchar(20)"` + "`" + `
}
database.SetAutoMigrate(&UserV2{})
字段操作
// 重命名字段
database.RenameColumn(&model.User{}, "UserName", "Nickname")
// 删除字段
database.DropColumn(&model.User{}, "OldField")
7. 高级特性
软删除
type User struct {
ID int64 `json:"id" db:"id"`
DeletedAt *time.Time `json:"deleted_at" db:"deleted_at"` // 软删除标记
}
// 自动过滤已删除记录
db.Model(&model.User{}).Find(&users) // WHERE deleted_at IS NULL
// 强制包含已删除记录
db.Unscoped().Model(&model.User{}).Find(&users)
调试模式
database:
debug: true # 输出所有 SQL 日志
DryRun 模式
// 生成 SQL 但不执行
sql, args := db.Model(&model.User{}).DryRun().Insert(&user)
fmt.Println(sql, args)
自定义 Handler
// 注册回调函数
db.Callback().Before("insert").Register("custom_before_insert", func(ctx context.Context, db *orm.DB) error {
// 自定义逻辑
return nil
})
主从集群
// 配置读写分离
db, err := orm.NewDatabase(&orm.Config{
DriverName: "mysql",
DataSource: "master_dsn",
Replicas: []string{"slave1_dsn", "slave2_dsn"},
})
最佳实践
1. 模型设计规范
// ✅ 推荐:使用 db 标签明确字段映射
type User struct {
ID int64 `json:"id" db:"id"`
Username string `json:"username" db:"username"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
}
// ❌ 不推荐:缺少字段映射标签
type User struct {
Id int64 // 无法自动映射到 id 列
UserName string // 可能映射错误
CreatedAt time.Time // 时间格式可能不匹配
}
2. 事务使用规范
// ✅ 推荐:使用闭包自动管理事务
err := db.Transaction(func(tx *orm.Tx) error {
// 业务逻辑
return nil
})
// ❌ 不推荐:手动管理事务
tx, err := db.Begin()
if err != nil {
panic(err)
}
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
3. 查询优化
// ✅ 推荐:使用 Select 指定字段
db.Model(&model.User{}).Select("id", "username").Find(&users)
// ✅ 推荐:使用 Index 加速查询
// 在数据库层面创建索引
// CREATE INDEX idx_username ON user(username);
// ✅ 推荐:批量操作
users := []model.User{{}, {}, {}}
db.BatchInsert(&users, 100) // 每批 100 条
// ❌ 避免:N+1 查询问题
for _, user := range users {
db.Model(&model.Order{}).Where("user_id = ?", user.ID).Find(&orders) // 循环查询
}
// ✅ 使用 Join 或预加载
db.Query(&results, "SELECT u.*, o.* FROM user u LEFT JOIN orders o ON u.id = o.user_id")
4. 错误处理
// ✅ 推荐:统一错误处理
if err := db.Insert(&user); err != nil {
log.Error("创建用户失败", "error", err)
return err
}
// ✅ 使用 errors 包判断特定错误
if errors.Is(err, sql.ErrNoRows) {
// 记录不存在
}
5. 性能优化
// 连接池配置
sqlDB := db.DB()
sqlDB.SetMaxIdleConns(10) // 最大空闲连接数
sqlDB.SetMaxOpenConns(100) // 最大打开连接数
sqlDB.SetConnMaxLifetime(time.Hour) // 连接最大生命周期
// 使用 Scan 替代 Find 提升性能
type Result struct {
ID int64 `db:"id"`
Username string `db:"username"`
}
var results []Result
db.Model(&model.User{}).Select("id", "username").Scan(&results)
常见问题
Q: 如何处理并发写入?
A: 使用事务 + 乐观锁:
type Product struct {
ID int64 `db:"id"`
Version int `db:"version"` // 版本号
}
// 更新时检查版本号
rows, err := db.Exec(
"UPDATE product SET version = ?, stock = ? WHERE id = ? AND version = ?",
newVersion, newStock, id, oldVersion,
)
count, _ := rows.RowsAffected()
if count == 0 {
return errors.New("乐观锁冲突,数据已被其他事务修改")
}
Q: 如何实现读写分离?
A: 配置主从数据库连接:
db, err := orm.NewDatabase(&orm.Config{
DriverName: "mysql",
DataSource: "master_dsn",
Replicas: []string{"slave1_dsn", "slave2_dsn"},
ReadPolicy: orm.RoundRobin, // 负载均衡策略
})
Q: 如何批量插入大量数据?
A: 使用 BatchInsert:
users := make([]model.User, 10000)
// ... 填充数据 ...
db.BatchInsert(&users, 1000) // 每批 1000 条,共 10 批
Q: 如何实现字段自动映射?
A: 框架会自动将驼峰命名转换为下划线命名:
type UserInfo struct {
UserName string `db:"user_name"` // 自动映射到 user_name 字段
UserAge int `db:"user_age"` // 自动映射到 user_age 字段
CreatedAt string `db:"created_at"` // 自动映射到 created_at 字段
}
Q: 如何处理时间字段?
A: 使用 time.Time 类型,框架会自动处理时区转换:
type Event struct {
ID int64 `db:"id"`
StartTime time.Time `db:"start_time"`
EndTime time.Time `db:"end_time"`
}
更新日志
- v1.0.0: 初始版本发布
- 完全自主研发,零依赖第三方 ORM
- 基于 database/sql 标准库
- 全自动化事务管理
- 智能字段映射
- OpenTelemetry 集成
- 支持 MySQL、SQLite、PostgreSQL
贡献指南
欢迎提交 Issue 和 Pull Request!
许可证
MIT License