Go 轻量 ORM,基于 database/sql,支持 MySQL 与 PostgreSQL。v2 采用泛型函数式 API。
go get github.com/lontten/ldb/v2完整可运行示例见 example/ 目录:
cd example
export LDB_MYSQL_HOST=127.0.0.1
export LDB_MYSQL_PORT=3306
export LDB_MYSQL_DB=test
export LDB_MYSQL_USER=root
export LDB_MYSQL_PWD=123456
go run . insert # 查看所有子命令: go run .建表示例见 example/dbinit/db.go 顶部注释。
import "github.com/lontten/ldb/v2"
conf := ldb.MysqlConf{
Host: "127.0.0.1",
Port: "3306",
DbName: "test",
User: "root",
Password: "123456",
}
db := ldb.MustConnect(&conf, nil)pgConf := ldb.PgConf{
Host: "127.0.0.1",
Port: "5432",
DbName: "test",
User: "postgres",
Password: "123456",
Other: "sslmode=disable TimeZone=Asia/Shanghai",
}
db := ldb.MustConnect(&pgConf, nil)poolConf := &ldb.PoolConf{
MaxIdleCount: 10,
MaxOpen: 100,
MaxLifetime: time.Hour,
Logger: log.New(os.Stdout, "", log.LstdFlags),
}
db, err := ldb.Connect(&conf, poolConf)表名、主键通过模型的 TableConf() 配置。临时换表使用 ldb.E().TableName("other_table")。
import (
"github.com/lontten/lcore/v2/types"
"github.com/lontten/ldb/v2"
)
type User struct {
Id *int `db:"id"`
Name *string `db:"name"`
Age *int `db:"age"`
}
func (User) TableConf() *ldb.TableConfContext {
return ldb.TableConf("t_user").
PrimaryKeys("id").
AutoColumn("id")
}
// 用于 W().Model() 条件查询,仅非 nil 字段参与 WHERE
type UserWhere struct {
Name *string
Age *int
}可空字段使用指针或 lcore/v2/types 类型,零值字段在 Insert/Update 时自动忽略。字段映射详见 doc/field.md。
user := User{
Name: types.NewString("tom"),
Age: types.NewInt(18),
}
num, err := ldb.Insert(db, &user, ldb.E().
WhenDuplicateKey("name").DoUpdate().
ShowSql(),
)
// num 为影响行数;若配置了自增主键,user.Id 会被回填// 按主键更新(主键字段从 dest 中读取)
user := User{
Id: types.NewInt(1),
Name: types.NewString("tom-updated"),
}
num, err := ldb.UpdateByPrimaryKey(db, &user, ldb.E().ShowSql())
// 按条件更新
patch := User{Name: types.NewString("patched")}
num, err = ldb.Update(db, &patch, ldb.W().
Eq("id", 1).
In("id", []int{1, 2}).
Gt("id", 0).
IsNull("age").
Like(types.NewString("tom"), "name"),
ldb.E().SetNull("age").ShowSql(),
)// 按主键
num, err := ldb.Delete[User](db, ldb.W().PrimaryKey(1), ldb.E().ShowSql())
// 按模型(非 nil 字段作为条件)
num, err = ldb.Delete[User](db, ldb.W().Model(UserWhere{
Name: types.NewString("tom"),
}), ldb.E().ShowSql())
// 按字段
num, err = ldb.Delete[User](db, ldb.W().Eq("name", "orphan"), ldb.E().ShowSql())// 查询单条,无记录时返回 nil
user, err := ldb.First[User](db, ldb.W().PrimaryKey(1), ldb.E().ShowSql())
// 查询列表
users, err := ldb.List[User](db, ldb.W().Model(UserWhere{
Name: types.NewString("tom"),
}), ldb.E().ShowSql())
// 是否存在
has, err := ldb.Has[User](db, ldb.W().Eq("name", "tom"), ldb.E().ShowSql())
// 计数
count, err := ldb.Count[User](db, ldb.W().Gt("id", 0), ldb.E().ShowSql())
// 不存在则插入
candidate := User{Name: types.NewString("new-user")}
result, err := ldb.GetOrInsert[User](db, ldb.W().Eq("name", "new-user"), &candidate, ldb.E().ShowSql())
exists, err := ldb.HasOrInsert(db, ldb.W().Eq("name", "other"), &User{Name: types.NewString("other")}, ldb.E().ShowSql())wb := ldb.W().
Eq("age", 18, true). // 第三个参数为 false 时跳过该条件
NotEq("name", "blocked").
In("id", []int{1, 2, 3}).
Like(types.NewString("tom"), "name"). // 第一个参数为 *string
Or(ldb.W().IsNull("age"))
users, err := ldb.List[User](db, wb, ldb.E().OrderBy("id").Limit(10).ShowSql())常用方法:
| 分类 | 方法 |
|---|---|
| 模型条件 | Model、Map、PrimaryKey、FilterPrimaryKey |
| 比较 | Eq、NotEq、In、NotIn、Gt、Gte、Lt、Lte、Between |
| 空值 | IsNull、IsNotNull |
| 模糊 | Like、LikeLeft、LikeRight、NoLike |
| 逻辑 | And、Or、Not |
| 原生 | Native、BoolNative |
详情见 doc/where.md。完整示例:example/demo_where.go
ldb.E().
ShowSql(). // 打印 SQL
NoRun(). // 只生成 SQL,不执行
TableName("t_other"). // 临时换表
AllowFullTableOp(). // 允许无 WHERE 的全表操作
SetNull("age"). // 更新时强制置 NULL
Set("state", 1). // 更新时设置字段
OrderBy("id"). // 查询排序
Limit(10). // 查询分页
WhenDuplicateKey("name").DoUpdate(ldb.Set().Set("state", 1)) // 插入冲突处理详情见 doc/insert2.md、doc/update2.md。
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
if _, err := ldb.Insert(tx, &user, ldb.E().ShowSql()); err != nil {
return err
}
return tx.Commit()完整示例:example/demo_insert.go 中 insert-tx 子命令。
list, err := ldb.QueryBuild[User](db).ShowSql().
Select("u.id").
Select("u.name").
Select("u.age").
From("t_user u").
BoolWhere(true, "u.name LIKE ?", "%tom%").
OrderDescBy("u.id").
Limit(20).
List()完整示例:example/demo_query_build.go · 文档:doc/builder.md
user, err := ldb.NativeQuery[User](db,
"SELECT id, name, age FROM t_user WHERE id = ?", 1,
).One()stmt, err := ldb.Prepare(db, "SELECT id, name FROM t_user WHERE id > ?")
var list []User
rowsNum, err := ldb.StmtQuery[User](stmt, 0).ScanList(&list)完整示例:example/demo_native.go · 文档:doc/native.md、doc/preper/stmt.md
| 文档 | 说明 |
|---|---|
| doc/db.md | 数据库初始化概览 |
| doc/insert2.md | 插入与冲突处理 |
| doc/update2.md | 更新扩展 |
| doc/select2.md | 查询扩展 |
| doc/del2.md | 删除扩展 |
| doc/where.md | 条件构造器 |
| doc/builder.md | QueryBuild |
| doc/native.md | 原生查询 |
| doc/hook.md | 钩子 |
| doc/one2many.md | 一对多 |
注:
doc/select.md、doc/del.md等无2后缀的文档可能仍含 v1 链式示例,请以本 README 及*2.md文档为准。
Apache License 2.0 — 见 LICENSE