那就写一个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

相关推荐
customer0829 分钟前
【开源免费】基于SpringBoot+Vue.JS个人博客系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
qq_4592384933 分钟前
SpringBoot整合Redis和Redision锁
spring boot·redis·后端
灰色人生qwer37 分钟前
SpringBoot 项目配置日志输出
java·spring boot·后端
阿华的代码王国1 小时前
【从0做项目】Java搜索引擎(6)& 正则表达式鲨疯了&优化正文解析
java·后端·搜索引擎·正则表达式·java项目·从0到1做项目
EQUINOX11 小时前
lab4 CSAPP:Cachelab
java·后端·spring
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS打卡健康评测系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
一小路一1 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
(; ̄ェ ̄)。2 小时前
在Nodejs中使用kafka(三)offset偏移量控制策略,数据保存策略
分布式·后端·kafka·node.js
paterWang2 小时前
基于SpringBoot的驾校报名小程序系统设计与实现(源码+文档)
spring boot·后端·小程序
苏生Susheng4 小时前
【SpringBoot整合系列】Kafka的各种模式及Spring Boot整合的使用基础案例
java·spring boot·后端·spring·kafka·消息队列·并发