Golang ORM库推荐与使用指南

Golang ORM库推荐与使用指南 最近开源了 gosql,一个采用 Go 语言风格语法的 ORM 库。

语法优雅,支持批量插入,轻松嵌套条件,处理各种复杂的查询 SQL,例如:and、or 组合。 完整语法支持:for update 锁、is null、exists 子查询等。基本上涵盖了所有 SQL 语法。

风格如下:

user: = & UserModel {}
err: = db.Fetch (user,
    gosql.Columns ("id", "name"),
    gosql.Where ("id", 1),
    gosql.Where ("[like] name", "j%")
    gosql.OrWhere (func (s * Clause) {
        s.Where ("[> =] score", "90")
        s.Where ("[<=] age", "100")
    }),
    GroupBy ("type"),
    OrderBy ("score DESC"),
)

特性

  • Go 语言风格的 SQL 生成
  • 无限嵌套查询
  • 读写分离
  • 延迟连接创建
  • ORM 映射结构
  • 事务支持
  • 功能多样
  • 代码简洁
  • 支持批量插入

github:

https://github.com/rushteam/gosql


更多关于Golang ORM库推荐与使用指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

感谢阅读,通常在编写原生SQL时,你会发现一些问题: "in"条件的占位符需要根据参数来确定 where条件的数量不易确定

更多关于Golang ORM库推荐与使用指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


SQL构建器的风格看起来相当奇怪。与SQL相比,示例中的Go代码怎么就更容易阅读了呢?对于条件表达式也可以这样说。为什么不直接写SQL呢?

演示:

package main

import (
    "fmt"

    _ "github.com/go-sql-driver/mysql"
    "github.com/rushteam/gosql"
)

type UserModel struct {
    ID   int    `db:"id"`
    Name string `db:"name"`
}

func (u *UserModel) TableName() string {
    return "my_user"
}

func main() {
    db := gosql.NewCluster(
        gosql.AddDb("mysql", "user:password@tcp(127.0.0.1:3306)/test?parseTime=true&amp;readTimeout=3s&amp;writeTimeout=3s&amp;timeout=3s"),
    )
    user := &amp;UserModel{}
    err := db.Fetch(user, gosql.Where("id", 1), gosql.Where("[like]name", "j%"))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(user)
}

gosql 的设计确实体现了 Go 语言的简洁风格,通过链式调用和闭包实现了灵活的查询构造。以下是一个完整的使用示例,展示其核心功能:

package main

import (
    "fmt"
    "github.com/rushteam/gosql"
)

type User struct {
    ID    int    `db:"id"`
    Name  string `db:"name"`
    Score int    `db:"score"`
    Age   int    `db:"age"`
    Type  string `db:"type"`
}

func main() {
    // 1. 初始化连接(支持延迟创建)
    db := gosql.NewDatabase("mysql", "user:pass@tcp(localhost:3306)/dbname")
    
    // 2. 单条查询(支持复杂条件嵌套)
    user := &User{}
    err := db.Fetch(user,
        gosql.Columns("id", "name", "score"),
        gosql.Where("[>] score", 80),
        gosql.OrWhere(func(s *gosql.Clause) {
            s.Where("[like] name", "张%")
            s.Where("[<] age", 30)
        }),
        gosql.ForUpdate(), // 行级锁
        gosql.OrderBy("score DESC"),
        gosql.Limit(1),
    )
    if err != nil {
        panic(err)
    }
    fmt.Printf("查询结果: %+v\n", user)
    
    // 3. 批量插入
    users := []User{
        {Name: "张三", Score: 95, Type: "A"},
        {Name: "李四", Score: 88, Type: "B"},
    }
    _, err = db.Table("users").Insert(users)
    if err != nil {
        panic(err)
    }
    
    // 4. 事务操作
    db.Transaction(func(tx *gosql.DB) error {
        // 更新操作
        _, err := tx.Table("users").
            Where("id", 1).
            Update(gosql.M{"score": gosql.Raw("score + ?", 10)})
        if err != nil {
            return err
        }
        
        // 子查询示例
        subQuery := gosql.NewClause().
            Table("logs").
            Columns("user_id").
            Where("[>] created_at", "2023-01-01")
        
        // 主查询
        var highScoreUsers []User
        err = tx.FetchAll(&highScoreUsers,
            gosql.Where("[in] id", subQuery),
            gosql.Where("[>] score", 90),
            gosql.GroupBy("type"),
            gosql.Having("[>] COUNT(*)", 1),
        )
        return err
    })
    
    // 5. 读写分离示例(需配置主从)
    masterDB := gosql.NewDatabase("mysql", "master_dsn")
    slaveDB := gosql.NewDatabase("mysql", "slave_dsn")
    cluster := gosql.NewCluster(masterDB, slaveDB)
    
    // 读操作自动走从库
    var readUser User
    cluster.Fetch(&readUser, gosql.Where("id", 1))
    
    // 写操作自动走主库
    cluster.Table("users").Insert(User{Name: "王五"})
}

关键特性实现说明:

  1. 复杂条件构建:通过 OrWhere 闭包实现无限嵌套

    gosql.OrWhere(func(s *gosql.Clause) {
        s.Where("[>] score", 90)
        s.AndWhere(func(s2 *gosql.Clause) {
            s2.Where("[<] age", 30)
            s2.OrWhere("[=] type", "VIP")
        })
    })
    
  2. 原生 SQL 支持

    // 使用 Raw 表达式
    gosql.Where("[>] score", gosql.Raw("(SELECT avg_score FROM stats)"))
    
    // EXISTS 子查询
    sub := gosql.NewClause().Table("orders").Columns("1").Where("user_id = users.id")
    gosql.Where(gosql.Exists(sub))
    
  3. 批量操作优化

    // 批量插入时自动优化为单条 SQL
    batch := make([]User, 1000)
    // ... 初始化数据
    db.Table("users").Insert(batch) // 生成: INSERT INTO users (...) VALUES (...),(...)
    
  4. 关联查询映射

    type UserDetail struct {
        User      `db:",inline"`
        OrderCount int `db:"order_count"`
    }
    
    var details []UserDetail
    db.FetchAll(&details,
        gosql.Joins("LEFT JOIN orders ON users.id = orders.user_id"),
        gosql.Columns("users.*", "COUNT(orders.id) as order_count"),
        gosql.GroupBy("users.id"),
    )
    

该库通过方法链保持 API 简洁,同时利用闭包处理复杂逻辑,避免了传统 ORM 的字符串拼接问题。事务支持通过回调函数确保自动提交/回滚,读写分离配置对业务代码透明。

回到顶部