blog
blog copied to clipboard
动手写ORM框架 - GeeORM第四天 链式操作与更新删除 | 极客兔兔
https://geektutu.com/post/geeorm-day4.html
7天用 Go语言/golang 从零实现 ORM 框架 GeeORM 教程(7 days implement golang object relational mapping framework from scratch tutorial),动手写 ORM 框架,参照 gorm, xorm 的实现。通过链式(chain)操作,支持查询条件(where, order by, limit 等)的叠加;实现记录的更新(update)、删除(delete)和统计(count)功能。
膜拜大佬
膜拜大佬
@xiaoxfan 哈哈,感谢认可,希望对你有帮助~
链式调用太精巧了,Find, Delete,Update 等都是调用置后的。PS 这里的 SQL 语句合法性没有做限制,需要用户自己把握
这里是为了省代码吗,感觉可读性太差了。。。
s.clause.Set(clause.WHERE, append(append(vars, desc), args...)...)
这种链式调用不会导致SQL注入吗?
func TestSession_DeleteAndCount(t *testing.T) {
s := testRecordInit(t)
affected, _ := s.Where("Name = ?", "Tom").Delete()
count, _ := s.Count()
if affected != 1 || count != 1 {
t.Fatal("failed to delete or count")
}
}
这里应该是count != 0
逻辑才对,affected, _ := s.Where("Name = ?", "Tom").Delete()
这个链式调用把clause.WHERE
也Set了会导致后面s.Count()
的时候把clause.WHERE
条件也加进去,也就是SELECT count(*) FROM User WHERE Name = ? [Tom]
。显然是 count 的值应该是 0 才对。
或者是否在clause.go 里面加一个 clear() 方法,在 Build 返回之前都调用一下?
@SeanChan0901
func TestSession_DeleteAndCount(t *testing.T) { s := testRecordInit(t) affected, _ := s.Where("Name = ?", "Tom").Delete() count, _ := s.Count() if affected != 1 || count != 1 { t.Fatal("failed to delete or count") } }
这里应该是
count != 0
逻辑才对,affected, _ := s.Where("Name = ?", "Tom").Delete()
这个链式调用把clause.WHERE
也Set了会导致后面s.Count()
的时候把clause.WHERE
条件也加进去,也就是SELECT count(*) FROM User WHERE Name = ? [Tom]
。显然是 count 的值应该是 0 才对。或者是否在clause.go 里面加一个 clear() 方法,在 Build 返回之前都调用一下?
s.Raw().Exec()中的方法Exec有clear的了。
lz可以拍个视频,手敲代码理解太累了
func TestSession_DeleteAndCount(t *testing.T) {
s := testRecordInit(t)
affected, _ := s.Where("Name = ?", "Tom").Delete()
count, _ := s.Count()
if affected != 1 || count != 1 {
t.Fatal("failed to delete or count")
}
}
这里执行两个sql语句,难道不需要清空s.clause里面的内容吗?我执行的话会出错,因为Count里面还用上了Where子句。
我在clause.Build函数里面添加一个清除操作,才能不会报错。作者是在其它地方添加了操作吗?
func (c *Clause)Build(orders ...Type)(string,[]interface{}) {
......
defer func() {
c.sql=nil
c.sqlVars=nil
}()
.....
}
@lcxc-lcxc
func TestSession_DeleteAndCount(t *testing.T) { s := testRecordInit(t) affected, _ := s.Where("Name = ?", "Tom").Delete() count, _ := s.Count() if affected != 1 || count != 1 { t.Fatal("failed to delete or count") } }
这里执行两个sql语句,难道不需要清空s.clause里面的内容吗?我执行的话会出错,因为Count里面还用上了Where子句。
我在clause.Build函数里面添加一个清除操作,才能不会报错。作者是在其它地方添加了操作吗?
func (c *Clause)Build(orders ...Type)(string,[]interface{}) { ...... defer func() { c.sql=nil c.sqlVars=nil }() ..... }
确实需要手动clear一下
@xiaoheng14 s.Raw().Exec()中的方法Exec有clear的了。
那个clear清空的是stringBuilder中缓存的sql语句,而不是子句中的各个条件
@haochen233 这里是为了省代码吗,感觉可读性太差了。。。
s.clause.Set(clause.WHERE, append(append(vars, desc), args...)...)
只是提供了一种思路,让初学者入门而已。配合着debug调试就好了。真正使用ORM不会这么繁琐的。例如调用laravel的时候都是高度封装成->where(field,value)
的形式