[官文译] Go轻量级ORM Bun - 简介

526 阅读2分钟

原文: What is Bun? (uptrace.dev)

版本:v1.1.17


Bun 是什么?

Bun 是用于 go 语言、SQL优先的数据库客户端。SQL优先意味着大多数 SQL 查询可自动编译为 Bun 表达式,并且 Bun 表达式看起来和用起来都像 SQL 查询。

Bun 的目标是可以使用之前好的 SQL 来编写查询,并辅助扫描结果到常用的 Go 类型:struct、map、切片 和 向量。

它如何工作

Bun 对 sql.DB 进行了封装,提供了查询 构建器 and 钩子。原始的 sql.DBdb.DB 来使用并且不受任何限制。

type DB struct {
	*sql.DB
    ...
}

Bun 为每个支持的数据提供 dialect(方言)。 Bun 使用 dialect 在编译查询和扫描查询结果时发现可用的特性。例如,要连接 PostgreSQL 服务器,需要使用 PostgreSQL 驱动(例,pgdriver)和 PostgreSQL 的 dialect (pgdialect)。

Bun 提供了用于加载初始数据的 fixture(固定装置) 和更新数据库模式的 migration(迁移处理)。也可以使用 Bun starter kit 来快速初始化一个使用这些包的应用。

为什么又要开发一个数据库客户端?

因为可以优雅地编写复杂的查询:

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

为什么不是。。。?

GORM

使用 Bun 编写复杂的查询通常比 GORM 更容易。 Bun 自身天然集成了特定数据库的基础功能,例,PostgreSQL 的数组。 Bun 也更快,部分是因为 Bun 在大小和作用域都更小。

Bun 不支持 GORM 的一些受欢迎的特性如自动迁移(可以使用 fixture 代替)、优化/索引/注释 提示、和数据库解析器。

Ent

使用 Bun ,可以运用以前 SQL DBMS 的经验并编写快速地道的代码。Bun 的目标是辅助编写 SQL ,而不是代替或隐藏 SQL 。

使用 Ent的话,以前的经验可能用不上,还可能产生误导。这是因为 Ent 提供了一种新的/不同的方式编写 Go 应用,所以除了遵循没有太多选择。

go-pg

Bun 是 go-pg 的重写,它基于 sql.DB 而不是自定义的 API 。因此,Bun 相比 go-pg 效率会稍微低一点儿,但它可用于不同的数据库。

很显然 Bun 会代替 go-pg 。要将现有的 go-pg 应用迁移到 Bun ,可查看 指南