那就写一个SQL库吧

一、起因

工作中一直在使用GORM,可能是项目类型或者个人风格的原因,我自己更偏向直接写SQL(因为避免不了),因此大多数时候只用到了GORM的对象映射和钩子,而对于钩子函数,我的观点是不使用,相应的逻辑应该显式写出来(方便阅读)。

所有我希望能有一款轻量的、接近标准库database/sql的工具,可以提供对象映射和表转结构体即可,基于此,我自己动手写了esql

二、主要功能

  • 对象映射
  • 自动化事务
  • 通过命令行/函数调用,生成表对应的模型文件(暂时只支持MySQL)
  • 通过结构体获取查询字段和更新字段
  • 提供日志接口,自定义日志输出

三、安装

  • 安装命令行工具
bash 复制代码
go install github.com/cyj19/esql/cmd/esql@latest
  • 安装esql
bash 复制代码
go get -u github.com/cyj19/esql@latest

四、使用方法

  • 连接
go 复制代码
dataSource := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local"
db, err := esql.Open(esql.Mysql, dataSource, nil)
if err != nil {
    log.Fatal(err)
}

err = db.Ping()
if err != nil {
    log.Fatal(err)
}
  • 查询单条记录
css 复制代码
userFieldNames := esql.RawFieldNames(User{})
userFields := esql.RawQueryFields(userFieldNames)
var user User
query := fmt.Sprintf("select %s from user where id=?", userFields)
err := db.QueryRow(&user, query, 2)
if err != nil {
    log.Fatal(err)
}

log.Println(user)
  • 查询多条记录
go 复制代码
userFieldNames := esql.RawFieldNames(&User{})
userFields := esql.RawQueryFields(userFieldNames)
var rows []*User
query := fmt.Sprintf("select %s from user", userFields)
err := db.QueryRows(&rows, query)
if err != nil {
    log.Fatal(err)
}

for _, row := range rows {
    log.Printf("%+v \n", row)
}
  • 执行
css 复制代码
user := User{
    Name: "ccc",
}
query := "insert into user(`name`) values(?)"
result, err := db.Exec(query, user.Name)
if err != nil {
    log.Fatal(err)
}

id, _ := result.LastInsertId()
user.ID = int(id)

log.Println(user)
  • 自动化事务
go 复制代码
err := db.Transaction(func(tx *esql.Tx) error {
    userFieldNames := esql.RawFieldNames(User{})
    userFields := esql.RawQueryFields(userFieldNames)
    var user User
    query := fmt.Sprintf("select %s from user where id=?", userFields)
    err := tx.QueryRow(&user, query, 2)
    if err != nil {
        return err
    }

    userFieldsWithPlaceHolder :=  esql.RawUpdateFieldsWithPlaceHolder(userFieldNames, "`id`")
    query = fmt.Sprintf("update user set %s where `id`=?", userFieldsWithPlaceHolder)
    result, err := tx.Exec(query, user.Name+"1", user.Age+1,  2)
    if err != nil {
        return err
    }

    log.Println(result.RowsAffected())
    return nil

})

if err != nil {
    log.Fatal(err)
}
  • 手动事务操作
go 复制代码
// 开启事务
tx, err := db.Begin()
if err != nil {
    log.Fatal(err)
}

....
if err != nil {
    // 回滚事务
    tx.Rollback()
    return err
}


// 提交事务
tx.Commit()
  • 代码生成
    命令行工具
bash 复制代码
dev@virtual-dev:~$esql
Usage of esql:
  -db string
        the database name
  -dsn string
        the dataSource
  -ip string
        the database ip (default "127.0.0.1")
  -mode string
        the database drive (default "mysql")
  -p string
        the database password
  -path string
        the path to save file (default "./")
  -port int
        the database port (default 3306)
  -tag
        the generated structure needs to be tagged
  -u string
        the database user (default "root")


dev@virtual-dev:~$ esql -db test -u root -p 123456 -path ./model

方法调用

go 复制代码
err := db.GenStructByTable(esql.Mysql, "test", "./model", false)
if err != nil {
    log.Println(err)
}
  • 自定义日志
go 复制代码
// 实现esql.Logger
type CustomLogger struct {
}

...

// 传入自定义的日志即可
db, err := esql.Open(esql.Mysql, dataSource, &CustomLogger{})
if err != nil {
    log.Fatal(err)
}

五、总结

esql提供的curd接口和database/sql高度类似,大大降低学习成本,其次还可以通过数据库表直接生成model文件,减少重复编码。

如果这个项目对你有帮助,希望能给个start支持下,感谢感谢!

项目地址:https://github.com/cyj19/esql

相关推荐
boring_11117 分钟前
全局id生成器生产方案
大数据·分布式·后端
brave_zhao1 小时前
使用Spring Boot实现WebSocket广播
spring boot·后端·websocket
ss2733 小时前
基于Springboot + vue实现的中医院问诊系统
java·spring boot·后端
左灯右行的爱情4 小时前
Redis 缓存并发问题深度解析:击穿、雪崩与穿透防治指南
java·数据库·redis·后端·缓存
南玖yy4 小时前
C++ 成员变量缺省值:引用、const 与自定义类型的初始化规则详解,引用类型和const类型的成员变量自定义类型成员是否可以用缺省值?
c语言·开发语言·c++·后端·架构·c++基础语法
不爱总结的麦穗4 小时前
面试常问!Spring七种事务传播行为一文通关
后端·spring·面试
小虚竹5 小时前
claude 3.7,极为均衡的“全能型战士”大模型,国内直接使用
开发语言·后端·claude·claude3.7
Yharim5 小时前
两个客户端如何通过websocket通信
spring boot·后端·websocket
bcbnb5 小时前
iOS 性能调优实战:三款工具横向对比实测(含 Instruments、KeyMob、Xlog)
后端
极客智谷5 小时前
Spring AI应用系列——基于ARK实现多模态模型应用
人工智能·后端