重复了很多次,我终于不再忍了
重复了很多次,我终于不再忍了
虽然我不做管理系统,但是在项目中和数据库打交道还是比较多的,经常会从数据库中 (比如 Mysql 、ClickHouse 等) 查询一些记录,偶尔也会写入一些数据,但是不多。
db访问的工具(或者说组件)有很多,无论orm 还是工具,底层都是一样的,大致分一下,无非是row转struct 不太一样,大致分为2类, 1 反射类,大多数orm ,sql工具,包括你写的工具,都属于此类, 2 代码生成类,比较有名的就是 sqlc (github.com/kyleconroy/sqlc)(直接写sql,然后generate go代码),还有就是ent(entgo.io)
个人认为,数据库是应用程序的重点,找一个好的工具还是必须的,代码生成式在效率和易用性方面都很出色
这一领域,我到不建议造轮子,除非有特殊的需求或者场景,采用成熟方案更合适
晁老师难得玩一次标题党:)。
哈喽,文中 [blockloop/scan](https://colobu.com/2024/05/08/db-query-helpers/github.com/blockloop/scan) 跳转链接好像是错误的
标准库 scan 确实恼火, 但除了scan, 其实抽象的已经非常到位, 足够使用了 orm或者sqlx sqlc个人也也都觉得不好用, orm引入的问题比解决的问题更多而且引入的问题对工程影响更恶劣尤其大项目, sqlx是把简单的问题复杂化了, sqlc性能友好, 但业务通常涉及额外的逻辑, 如果涉及重新生成每次还要cv修改一些地方也是麻烦
所以我也忍不了, 搞了sqlw, 主要是做map映射, 增改查自动绑定, 删不涉及那么多复杂只是简单接口统一封装: https://github.com/lesismal/sqlw
举例子:
Insert One Records
model := Model{
I: 1,
S: "str_1",
}
result, err := db.Insert("insert into sqlw_test.sqlw_test", &model)
// result, err := db.Insert("insert into sqlw_test.sqlw_test(i,s)", &model) // insert the specified fields
if err != nil {
log.Panic(err)
}
log.Println("sql:", result.Sql())
Insert Multi Records
var models []*Model
for i:=0; i<3; i++{
models = append(models, &Model{
I: i,
S: fmt.Sprintf("str_%v", i),
})
}
result, err := db.Insert("insert into sqlw_test.sqlw_test", models)
// result, err := db.Insert("insert into sqlw_test.sqlw_test(i,s)", models) // insert the specified fields
if err != nil {
log.Panic(err)
}
log.Println("sql:", result.Sql())
Delete
deleteId := 1
result, err := db.Delete("delete from sqlw_test.sqlw_test where id=?", deleteId)
if err != nil {
log.Panic(err)
}
log.Println("sql:", result.Sql())
Update
m := Model{
I: 10,
S: "str_10",
}
updateId := 1
result, err := db.Update("update sqlw_test.sqlw_test set i=?, s=? where id=?", &m, updateId)
if err != nil {
log.Panic(err)
}
log.Println("sql:", result.Sql())
Select One Record
var model Model
selectId := 1
result, err := db.Select(&model, "select * from sqlw_test.sqlw_test where id=?", selectId)
// result, err := db.Select(&model, "select (i,s) from sqlw_test.sqlw_test where id=?", selectId) // select the specified fields
if err != nil {
log.Panic(err)
}
log.Println("model:", model)
log.Println("sql:", result.Sql())
Select Multi Records
var models []*Model // type []Model is also fine
result, err = db.Select(&models, "select * from sqlw_test.sqlw_test")
// result, err = db.Select(&models, "select (i,s) from sqlw_test.sqlw_test") // select the specified fields
if err != nil {
log.Panic(err)
}
for i, v := range models {
log.Printf("models[%v]: %v", i, v)
}
log.Println("sql:", result.Sql())