go-sqlbuilder 是一个用于构建 SQL 语句的 Go 语言库,它提供了灵活、强大且易于使用的工具来构建 SQL 字符串和相关参数。它支持多种数据库系统,包括 MySQL、PostgreSQL、SQLServer、SQLite、CQL、ClickHouse、Presto 和 Oracle。使用 go-sqlbuilder 可以帮助开发者避免直接字符串拼接带来的 SQL 注入风险,同时使代码更加易读和易维护。

安装

你可以通过 go get 命令来安装 go-sqlbuilder

go get github.com/huandu/go-sqlbuilder

基本使用

以下是使用 go-sqlbuilder 构建简单 SQL 语句的示例:

package main

import (
	"fmt"
	"github.com/huandu/go-sqlbuilder"
)

func main() {
	// 构建 SQL 语句
	sql := sqlbuilder.Select("id", "name").From("demo.user").
		Where("status = 1").Limit(10).
		String()
	fmt.Println(sql)
	// 输出:
	// SELECT id, name FROM demo.user WHERE status = 1 LIMIT 10
}

预定义的 SQL 构建器

go-sqlbuilder 提供了以下预定义的构建器:

  • Struct:根据结构体生成构建器的工厂函数。
  • CreateTableBuilder:构建 CREATE TABLE 语句。
  • SelectBuilder:构建 SELECT 语句。
  • InsertBuilder:构建 INSERT 语句。
  • UpdateBuilder:构建 UPDATE 语句。
  • DeleteBuilder:构建 DELETE 语句。
  • UnionBuilder:构建 UNIONUNION ALL 语句。
  • CTEBuilder:构建公用表表达式(CTE)。
  • Buildf:使用 fmt.Sprintf 类似的语法构建。
  • Build:使用特殊语法构建。
  • BuildNamed:使用 ${key} 引用 map 类型参数值构建。

构建 WHERE 子句

WHERE 子句是 SQL 语句中非常重要的部分。go-sqlbuilder 提供了 Cond 类型来简化 WHERE 子句的构建:

sb := sqlbuilder.Select("id").From("user")
sb.Where(
	sb.In("status", 1, 2, 5),
	sb.Or(
		sb.Equal("name", "foo"),
		sb.Like("email", "foo@%"),
	),
)
sql, args := sb.Build()
fmt.Println(sql)
fmt.Println(args)
// 输出:
// SELECT id FROM user WHERE status IN (?, ?, ?) AND (name = ? OR email LIKE ?)
// [1 2 5 foo foo@%]

构建针对不同数据库系统的 SQL 语句

不同的数据库系统可能使用不同的 SQL 语法和参数标记。go-sqlbuilder 引入了 “flavor” 的概念来解决这个问题。

使用 Struct 作为轻量级 ORM

Struct 类型存储了结构体的类型信息和字段信息,可以作为构建器的工厂。使用 Struct 的方法可以创建初始化的 SELECT/INSERT/UPDATE/DELETE 构建器,方便操作结构体数据。

嵌套 SQL

go-sqlbuilder 可以很容易地创建嵌套 SQL 语句:

sb := sqlbuilder.NewSelectBuilder()
fromSb := sqlbuilder.NewSelectBuilder()
statusSb := sqlbuilder.NewSelectBuilder()
sb.Select("id")
sb.From(sb.BuilderAs(fromSb, "user"))
sb.Where(sb.In("status", statusSb))
fromSb.Select("id").From("user").Where(fromSb.GreaterThan("level", 4))
statusSb.Select("status").From("config").Where(statusSb.Equal("state", 1))
sql, args := sb.Build()
fmt.Println(sql)
fmt.Println(args)
// 输出:
// SELECT id FROM (SELECT id FROM user WHERE level > ?) AS user WHERE status IN (SELECT status FROM config WHERE state = ?)
// [4 1]

自由格式构建器

如果需要构建包含大量特殊语法的复杂 SQL 语句,可以使用 Buildf 函数:

sb := sqlbuilder.NewSelectBuilder()
sb.Select("id").From("user")
explain := sqlbuilder.Buildf("EXPLAIN %v LEFT JOIN SELECT * FROM banned WHERE state IN (%v, %v)", sb, 1, 2)
sql, args := explain.Build()
fmt.Println(sql)
fmt.Println(args)
// 输出:
// EXPLAIN SELECT id FROM user LEFT JOIN SELECT * FROM banned WHERE state IN (?, ?)
// [1 2]

总结

go-sqlbuilder 提供了一种灵活、高效且易于使用的 SQL 语句构建方案,它可以帮助 Go 语言开发者更轻松地处理数据库操作。它既可以作为纯粹的 SQL 语句构建工具,也可以充当轻量级的 ORM 框架,满足不同场景下的需求。