bun:基于 Golang 生态的 SQL-first ORM 项目

SQL-first Golang ORM

Branch13Tags1148
This repository is empty

Bun: SQL-first Golang ORM

build workflow PkgGoDev Documentation Chat Gurubase

轻量级、SQL优先的Golang ORM,支持PostgreSQL、MySQL、MSSQL、SQLite和Oracle

Bun 是一款现代 ORM,它拥抱 SQL 而非将其隐藏。用 Go 编写复杂查询时,既能保证类型安全、具备强大的扫描能力,又能编写可在多种 SQL 数据库间通用的代码。

✨ 核心特性

  • SQL优先理念 - 编写优雅、易读且贴近 SQL 风格的查询
  • 多数据库支持 - PostgreSQL、MySQL/MariaDB、MSSQL、SQLite 和 Oracle
  • 类型安全操作 - 利用 Go 的静态类型检查实现编译时安全
  • 灵活扫描功能 - 将查询结果扫描到结构体、映射、标量或切片中
  • 性能优化设计 - 基于 database/sql 构建,开销极小
  • 丰富关系定义 - 通过结构体标签定义复杂的表关系
  • 生产环境就绪 - 支持迁移、测试数据、软删除和 OpenTelemetry

🚀 快速开始

go get github.com/uptrace/bun

基础示例

package main

import (
    "context"
    "database/sql"
    "fmt"

    "github.com/uptrace/bun"
    "github.com/uptrace/bun/dialect/sqlitedialect"
    "github.com/uptrace/bun/driver/sqliteshim"
)

func main() {
    ctx := context.Background()

    // Open database
    sqldb, err := sql.Open(sqliteshim.ShimName, "file::memory:")
    if err != nil {
        panic(err)
    }

    // Create Bun instance
    db := bun.NewDB(sqldb, sqlitedialect.New())

    // Define model
    type User struct {
        ID   int64  `bun:",pk,autoincrement"`
        Name string `bun:",notnull"`
    }

    // Create table
    db.NewCreateTable().Model((*User)(nil)).Exec(ctx)

    // Insert user
    user := &User{Name: "John Doe"}
    db.NewInsert().Model(user).Exec(ctx)

    // Query user
    err = db.NewSelect().Model(user).Where("id = ?", user.ID).Scan(ctx)
    fmt.Printf("User: %+v\n", user)
}

🎯 为何选择 Bun?

优雅的复杂查询

编写复杂查询时保持其可读性和可维护性:

regionalSales := db.NewSelect().
    ColumnExpr("region").
    ColumnExpr("SUM(amount) AS total_sales").
    TableExpr("orders").
    GroupExpr("region")

topRegions := db.NewSelect().
    ColumnExpr("region").
    TableExpr("regional_sales").
    Where("total_sales > (SELECT SUM(total_sales) / 10 FROM regional_sales)")

var results []struct {
    Region       string `bun:"region"`
    Product      string `bun:"product"`
    ProductUnits int    `bun:"product_units"`
    ProductSales int    `bun:"product_sales"`
}

err := db.NewSelect().
    With("regional_sales", regionalSales).
    With("top_regions", topRegions).
    ColumnExpr("region, product").
    ColumnExpr("SUM(quantity) AS product_units").
    ColumnExpr("SUM(amount) AS product_sales").
    TableExpr("orders").
    Where("region IN (SELECT region FROM top_regions)").
    GroupExpr("region, product").
    Scan(ctx, &results)

灵活的结果扫描

将查询结果扫描到各种 Go 类型中:

// Into structs
var users []User
db.NewSelect().Model(&users).Scan(ctx)

// Into maps
var userMaps []map[string]interface{}
db.NewSelect().Table("users").Scan(ctx, &userMaps)

// Into scalars
var count int
db.NewSelect().Table("users").ColumnExpr("COUNT(*)").Scan(ctx, &count)

// Into individual variables
var id int64
var name string
db.NewSelect().Table("users").Column("id", "name").Limit(1).Scan(ctx, &id, &name)

📊 数据库支持

数据库 驱动 方言
PostgreSQL github.com/uptrace/bun/driver/pgdriver pgdialect.New()
MySQL/MariaDB github.com/go-sql-driver/mysql mysqldialect.New()
SQLite github.com/uptrace/bun/driver/sqliteshim sqlitedialect.New()
SQL Server github.com/denisenkom/go-mssqldb mssqldialect.New()
Oracle github.com/sijms/go-ora/v2 oracledialect.New()

🔧 高级特性

表关系

通过结构体标签定义复杂关系:

type User struct {
    ID      int64   `bun:",pk,autoincrement"`
    Name    string  `bun:",notnull"`
    Posts   []Post  `bun:"rel:has-many,join:id=user_id"`
    Profile Profile `bun:"rel:has-one,join:id=user_id"`
}

type Post struct {
    ID     int64 `bun:",pk,autoincrement"`
    Title  string
    UserID int64
    User   *User `bun:"rel:belongs-to,join:user_id=id"`
}

// Load users with their posts
var users []User
err := db.NewSelect().
    Model(&users).
    Relation("Posts").
    Scan(ctx)

批量操作

针对大型数据集的高效批量操作:

// Bulk insert
users := []User{{Name: "John"}, {Name: "Jane"}, {Name: "Bob"}}
_, err := db.NewInsert().Model(&users).Exec(ctx)

// Bulk update with CTE
_, err = db.NewUpdate().
    Model(&users).
    Set("updated_at = NOW()").
    Where("active = ?", true).
    Exec(ctx)

// Bulk delete
_, err = db.NewDelete().
    Model((*User)(nil)).
    Where("created_at < ?", time.Now().AddDate(-1, 0, 0)).
    Exec(ctx)

迁移

为您的数据库模式添加版本控制:

import "github.com/uptrace/bun/migrate"

migrations := migrate.NewMigrations()

migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
    _, err := db.NewCreateTable().Model((*User)(nil)).Exec(ctx)
    return err
}, func(ctx context.Context, db *bun.DB) error {
    _, err := db.NewDropTable().Model((*User)(nil)).Exec(ctx)
    return err
})

migrator := migrate.NewMigrator(db, migrations)
err := migrator.Init(ctx)
err = migrator.Up(ctx)

📈 监控与可观测性

调试查询

为开发环境启用查询日志记录:

import "github.com/uptrace/bun/extra/bundebug"

db.AddQueryHook(bundebug.NewQueryHook(
    bundebug.WithVerbose(true),
))

OpenTelemetry 集成

具备分布式追踪功能的生产级可观测性:

import "github.com/uptrace/bun/extra/bunotel"

db.AddQueryHook(bunotel.NewQueryHook(
    bunotel.WithDBName("myapp"),
))

轻松实现监控:Bun 由 ⭐ uptrace/uptrace 为您呈现。Uptrace 是一款开源 APM 工具,支持分布式追踪、指标监控和日志管理。您可以使用它监控应用程序,并设置自动告警,通过电子邮件、Slack、Telegram 等渠道接收通知。

请参见 OpenTelemetry 示例,该示例演示了如何使用 Uptrace 监控 Bun。

📚 文档与资源

🤝 贡献

我们欢迎贡献!有关如何开始的详细信息,请参见我们的 贡献指南

感谢所有贡献者:

Contributors

🔗 相关项目


如果您觉得 Bun 有用,请给这个仓库点个星 ⭐!
加入我们的 Discord 社区 • 在 GitHub 上关注更新

Introduction

uptrace/bun:是一款基于 Rust 语言构建的 SQL 框架,具备对 PostgreSQL、MySQL、SQLite3 等多种数据库的支持。该框架非常适合开发高性能、可扩展的 Web 应用程序,尤其是在需要运用 Rust 语言以及 SQL 数据库的项目中。其显著特性包括:采用 Rust 语言、具备高性能、可扩展性强,并兼容多种数据库。【此简介由AI生成】

Customize your domain
314.97 K303Visit GitHub