
Bun
轻量级 Go 语言 ORM,适用于 PostgreSQL、MySQL、MSSQL 和 SQLite
以 SQL 为先
Bun 的目标是帮助您编写 SQL,而不是将其隐藏在笨拙的结构后面。
*sql.DB 兼容
Bun 使用 database/sql 并以兼容且惯用的方式对其进行扩展。
数据库无关
开箱即用,支持 PostgreSQL、MySQL 5.7+、MSSQL 和 SQLite。
迁移
使用 Go 和基于 SQL 的迁移来保持您的数据库模式更新。
夹具
使用 YAML 夹具为您的应用程序提供初始数据。
入门套件
现代应用程序框架将所有内容整合在一起,帮助您入门。
为什么是另一个 Go 语言 ORM?
这样您就可以优雅地编写复杂的查询
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)")
err := db.NewSelect().
With("regional_sales", regionalSales).
With("top_regions", topRegions).
ColumnExpr("region").
ColumnExpr("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").
GroupExpr("product").
Scan(ctx)
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product
快速入门
package main
import (
"context"
"database/sql"
"fmt"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/sqlitedialect"
"github.com/uptrace/bun/driver/sqliteshim"
"github.com/uptrace/bun/extra/bundebug"
)
func main() {
ctx := context.Background()
// Open an in-memory SQLite database.
sqlite, err := sql.Open(sqliteshim.ShimName, "file::memory:?cache=shared")
if err != nil {
panic(err)
}
// Create a Bun db on top of it.
db := bun.NewDB(sqlite, sqlitedialect.New())
// Print all queries to stdout.
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
var rnd int64
// Select a random number.
if err := db.NewSelect().ColumnExpr("random()").Scan(ctx, &rnd); err != nil {
panic(err)
}
fmt.Println(rnd)
}
package main
import (
"context"
"database/sql"
"fmt"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/pgdialect"
"github.com/uptrace/bun/driver/pgdriver"
"github.com/uptrace/bun/extra/bundebug"
)
func main() {
ctx := context.Background()
// Open a PostgreSQL database.
dsn := "postgres://postgres:@localhost:5432/test?sslmode=disable"
pgdb := sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
// Create a Bun db on top of it.
db := bun.NewDB(pgdb, pgdialect.New())
// Print all queries to stdout.
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
var rnd float64
// Select a random number.
if err := db.NewSelect().ColumnExpr("random()").Scan(ctx, &rnd); err != nil {
panic(err)
}
fmt.Println(rnd)
}
package main
import (
"context"
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/mysqldialect"
"github.com/uptrace/bun/extra/bundebug"
)
func main() {
ctx := context.Background()
// Open a MySQL 5.7+ database.
sqldb, err := sql.Open("mysql", "root:pass@/test")
if err != nil {
panic(err)
}
// Create a Bun db on top of it.
db := bun.NewDB(sqldb, mysqldialect.New())
// Print all queries to stdout.
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
var rnd float64
// Select a random number.
if err := db.NewSelect().ColumnExpr("rand()").Scan(ctx, &rnd); err != nil {
panic(err)
}
fmt.Println(rnd)
}
package main
import (
"context"
"database/sql"
"fmt"
_ "github.com/denisenkom/go-mssqldb"
"github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/mssqldialect"
"github.com/uptrace/bun/extra/bundebug"
)
func main() {
ctx := context.Background()
// Open a MSSQL database.
sqldb, err := sql.Open("sqlserver", "sqlserver://sa:passWORD1@localhost:1433?database=test")
if err != nil {
panic(err)
}
// Create a Bun db on top of it.
db := bun.NewDB(sqldb, mssqldialect.New())
// Print all queries to stdout.
db.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true)))
var rnd float64
// Select a random number.
if err := db.NewSelect().ColumnExpr("rand()").Scan(ctx, &rnd); err != nil {
panic(err)
}
fmt.Println(rnd)
}