之前用 beego 中自带的 orm,感觉有一些不是很满足需求的地方,而且想要尝试一些新的 orm,写一篇记录一下。
为裕安等地区用户提供了全套网页设计制作服务,及裕安网站建设行业解决方案。主营业务为成都网站建设、网站建设、裕安网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
在 xorm 和 gorm 之间对比了一下:
p.s. 需要说明的是,对比非常初级,而且项目处于很早期,也抱着尝试一下不行再改的心理,并没有想要得到一个孰优孰劣的结论。
想来想去,对于一个成熟的项目可能 gorm 更适合,但是 xorm 好像近期在频繁 commit,有一种想要追赶的意思。
那我先试试 xorm ,不知道为什么选的这个,可能是想试试看新款吧。(大雾
2017/07/04
可怕,xorm 不支持外键关系。一对一啥的。
这几天golang社区对泛型的讨论非常多的,一片热火朝天的景象。对我们广大gopher来说总归是好事。
泛型很有可能会颠覆我们之前的很多设计,带着这种疑问和冲动,我准备尝试用golang泛型实现几个orm的常见功能。
本文并没完全实现通用的orm,只是探讨其实现的一种方式提供各位读者做借鉴。
虽然golang有了泛型,但是目前在标准库sql底层还没有改造,目前还有很多地方需要用到reflect。
调用方式
这个部分跟传统的orm使用上没有太大区别,没办法不使用反射的情况下,泛型的方式可能变得有点繁琐。
调用方式
和创建table类似,写入数据好像比没有之前的orm有优势。
读取数据是非常高频的操作,所以我们稍作封装。
调用方式
稍微比原先的orm方式有了多一点想象空间,比如 在[T any]做更明确的约束,比如要求实现Filter定制方法。
鉴于本人能力还认证有限,目前还没有发现泛型对orm剧烈的改进和突破的可能。未来如果go对底层sql做出改动,或者实现诸如Rust那种Enum方式,可能会带来更多的惊喜。
models.go
============================
package main
import (
"github.com/astaxie/beego/orm"
)
type User struct {
Id int
Name string
Profile *Profile `orm:"rel(one)"` // OneToOne relation
}
type Profile struct {
Id int
Age int16
User *User `orm:"reverse(one)"` // 设置反向关系(可选)
}
func init() {
// 需要在init中注册定义的model
orm.RegisterModel(new(User), new(Profile))
}
main.go
==============
package main
import (
"fmt"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
func init() {
//orm.RegisterModel(new(User))
orm.RegisterDataBase("default", "mysql", "ta3:ta3@/ta3?charset=utf8")
orm.RunSyncdb("default", false, true) // true 改成false,如果表存在则会给出提示,如果改成false则不会提示 , 这句话没有会报主键不存在的错误
}
func main() {
o := orm.NewOrm()
o.Using("default") // 默认使用 default,你可以指定为其他数据库
user := User{Id: 1}
err := o.Read(user)
if err == orm.ErrNoRows {
fmt.Println("查询不到")
} else if err == orm.ErrMissPK {
fmt.Println("找不到主键")
} else {
fmt.Println(user.Id, user.Name)
}
}
执行结果:
create table `user`
-- --------------------------------------------------
-- Table Structure for `main.User`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `user` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(255) NOT NULL,
`profile_id` integer NOT NULL UNIQUE
) ENGINE=InnoDB;
create table `profile`
-- --------------------------------------------------
-- Table Structure for `main.Profile`
-- --------------------------------------------------
CREATE TABLE IF NOT EXISTS `profile` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`age` smallint NOT NULL
) ENGINE=InnoDB;
查询不到
第二次再执行:
table `user` already exists, skip
table `profile` already exists, skip
查询不到
如果 orm.RunSyncdb("default", false, true)改成 orm.RunSyncdb("default", false, false)
则执行结果不会提示。