New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beego ORM模块建议 #384

Closed
fingerQin opened this Issue Dec 17, 2013 · 24 comments

Comments

Projects
None yet
@fingerQin
Copy link

fingerQin commented Dec 17, 2013

例如,我有如下代码:

var hotCourse []models.VCourse
sql = "SELECT * FROM v_course ORDER BY hits DESC LIMIT 4"
o.Raw(sql).QueryRows(&hotCourse)

传入的hotCourse对应的models.VCourse里面的字段与数据库里面的字段顺序要一致才能将预期的字段值设置到VCourse的字段里面去。

如:
type VCourse struct{
Id int64
Name string
}

那么sql语句里面必须SELECT id,name FROM table才能将字段的值绑定上去。这很不方便。

我希望是这样的:
当我的结构体只有两个字段:Id与Name,那么,在结果绑定到结构体上的时候,先遍历结构体的字段,按照Model的定义(即与表字段之间的定义)进行查找SQL里面的字段,然后将该字段的值绑定到结构体的对应字段上。这样就很完善了。

在编写代码的时候,就不用再担心字段顺序的问题了。也不用担心,结构体的字段只有2个,而SQL字段有3个,导致匹配不上而报错了。

能否请设计ORM的大神改善一下原生SQL语句的智能能力呢。谢谢!

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 18, 2013

之前有考虑这个问题,解析SQL的话太麻烦,兼容性不够。复杂 sql 语句难处理啊。

目前其实是考虑这种用法的,使用临时的 struct 来接收数据

如:

type TmpData struct{
    Name string
    Title string
}

data := &Data{}
// ...QueryRows(&data)
@fingerQin

This comment has been minimized.

Copy link

fingerQin commented Dec 18, 2013

@slene 的确有些麻烦。这个看能不能找到相关的SQL解析器的东西来帮助一下。不然,这个太痛苦了。

@sunminghong

This comment has been minimized.

Copy link

sunminghong commented Dec 26, 2013

我昨天没有看这个issues,结果我折腾了一个多小时才发现是这个原因。@slence不实现这个是不是因为性能原因吗?

@fingerQin

This comment has been minimized.

Copy link

fingerQin commented Dec 26, 2013

@sunminghong 应该不是性能原因,估计是复杂度的问题。我觉得PHP的一些框架的ORM设计还是很好的。虽然,我不太赞成过于复杂的ORM.

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 26, 2013

推荐几个好的ORM设计,我来参考一下,嘿嘿

@fingerQin

This comment has been minimized.

Copy link

fingerQin commented Dec 26, 2013

@slene 目前没有用到特别简洁且方便的ORM。都是在使用各个PHP框架的时候,每个框架里面都有一些特别赞的操作。

@sunminghong

This comment has been minimized.

Copy link

sunminghong commented Dec 26, 2013

@phpqinsir ,哦。

@slene ,请问:不用raw(sql) ,用一下方法时,还需要考虑数据库字段的顺序吗?
num, err = at2.Filter("id__in",strings.Split(self.Army,",")).All(&heros)

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 26, 2013

这个不需要考虑字段顺序

@lidashuang

This comment has been minimized.

Copy link

lidashuang commented Dec 26, 2013

@slene
Rails ActiveRecord 很赞啊

@sunminghong

This comment has been minimized.

Copy link

sunminghong commented Dec 26, 2013

@slene ,ok !

@fingerQin

This comment has been minimized.

Copy link

fingerQin commented Dec 26, 2013

@slene 用Raw()这种形式,我好忧伤。特别是要考虑顺序。因为我的字段都已经按照ORM的规则编写的,那么,也可以通过其推导出我要取的字段。so.....我该怎么破不考虑字段顺序的问题。其实,那个IN里面的问号的问题,都没有这个紧迫。

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 26, 2013

之前主要是考虑到这种功能,就做成那个样了。使用临时的 struct 没问题

type User struct {
    Id   int
    Name string
}

type Profile struct {
    Id   int
    Age  int
}

var users []*User
var profiles []*Profile
err := o.Raw(`SELECT id, name, p.id, p.age FROM user
    LEFT OUTER JOIN profile AS p ON p.id = profile_id WHERE id = ?`, 1).QueryRows(&users, &profiles)

不过现在来看这种也不常用吧?

砍掉这个以后,可以通过获取的字段名对应到 struct 里。

支持ORM的设置 - column(column_name)

type User struct {
    Id int
    Name string `orm:"column(user_name)"`
}
  1. 目前的这种 QueryRows 支持多个类型 struct 匹配功能需要保留么?
  2. 砍掉功能后,使用字段名匹配,这样改进如何?
@sunminghong

This comment has been minimized.

Copy link

sunminghong commented Dec 26, 2013

@slene ,我认为这个功能应该不常用,可以砍掉这个功能

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 26, 2013

@phpqinsir 认为如何

@fingerQin

This comment has been minimized.

Copy link

fingerQin commented Dec 26, 2013

@slene 对的。可以砍掉。因为,在QueryRows里面传递两个对象真心没用到啊。也没有那种需求。我在PHP框架里面也没有遇到过这种ORM。所以,可以去掉的。谢谢噢。

@slene

This comment has been minimized.

Copy link
Collaborator

slene commented Dec 26, 2013

OK 改进

slene added a commit that referenced this issue Dec 30, 2013

@bronze1man

This comment has been minimized.

Copy link
Contributor

bronze1man commented Jan 9, 2014

@slene PHP的orm库,我用过Doctrine2,本身代码复杂度太高了.
自定义了一个dql查询语言,比较鸡肋,一般使用QueryBuilder.

@qinerg

This comment has been minimized.

Copy link

qinerg commented Jan 10, 2014

@slene 也可以参考下 java 的 Nutz 框架中的 Dao,也很简单方便。它有一个从单独文件中加载sql的功能,可以将sql语句从代码中剥离出来,维护起来非常很爽。

@bronze1man

This comment has been minimized.

Copy link
Contributor

bronze1man commented Jan 10, 2014

这个问题本身不是很复杂.
只需要先把数据库的查询结果变成一个[]map[string]string,再把数据填回用户输入的结构体里面就好了..

此处代码可以把数据库的查询结果变成一个[]map[string]string
https://github.com/bronze1man/kmg/blob/master/kmgSql/QueryGrid.go

@blacklee

This comment has been minimized.

Copy link
Contributor

blacklee commented Jan 13, 2015

用惯了Rails的ActiveRecord后再看Beego的,感觉相当的不便利。不奢望能在查询时返回ActiveRecord::Relation,但是至少能有ActiveRecord::Base里定义好的那么多便利的方法呀。

@yanxiyue

This comment has been minimized.

Copy link

yanxiyue commented Feb 11, 2015

raw sql的功能建议可以参考一下mybatis的实现方式。

@xiaoDC

This comment has been minimized.

Copy link

xiaoDC commented Apr 6, 2015

func Query(id int64, obj interface{})(interface{}, interface{}){
oo := orm.NewOrm()
objtype := reflect.TypeOf(obj).Name()
fmt.Println(objtype)
err := oo.Raw("SELECT id, name, password FROM " + strings.ToLower(objtype) + " WHERE id = ?", id).QueryRow(&obj)
fmt.Println(obj)
return obj, err
}

请问为什么我查找得到的对象是一个interface时就查找不到,必须给具体的struct吗?那我不是每个model中都得写CRUD方法?!

@wuranbo

This comment has been minimized.

Copy link
Contributor

wuranbo commented Apr 21, 2015

type User struct {
Id int
Name string
Profiles []*Profile
}

type Profile struct {
Id int
Age int
}

var users []*User
err := o.Raw(SELECT id, name, p.id, p.age FROM user LEFT OUTER JOIN profile AS p ON p.id = profile_id WHERE id = ?, 1).QueryRows(&users, User.Profiles)

怎么能一次select把related也弄到呢?

@lei-cao

This comment has been minimized.

Copy link
Contributor

lei-cao commented Dec 30, 2015

@winerQin Thank you for supporting beego. please update or submit your issue in English for a better international user friendly communication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment