例如,我有如下代码:
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语句的智能能力呢。谢谢!
之前有考虑这个问题,解析SQL的话太麻烦,兼容性不够。复杂 sql 语句难处理啊。
目前其实是考虑这种用法的,使用临时的 struct 来接收数据
如:
type TmpData struct{
Name string
Title string
}
data := &Data{}
// ...QueryRows(&data)
@slene 的确有些麻烦。这个看能不能找到相关的SQL解析器的东西来帮助一下。不然,这个太痛苦了。
我昨天没有看这个issues,结果我折腾了一个多小时才发现是这个原因。@slence不实现这个是不是因为性能原因吗?
@sunminghong 应该不是性能原因,估计是复杂度的问题。我觉得PHP的一些框架的ORM设计还是很好的。虽然,我不太赞成过于复杂的ORM.
推荐几个好的ORM设计,我来参考一下,嘿嘿
@slene 目前没有用到特别简洁且方便的ORM。都是在使用各个PHP框架的时候,每个框架里面都有一些特别赞的操作。
@phpqinsir ,哦。
@slene ,请问:不用raw(sql) ,用一下方法时,还需要考虑数据库字段的顺序吗?
num, err = at2.Filter("id__in",strings.Split(self.Army,",")).All(&heros)
这个不需要考虑字段顺序
@slene
Rails ActiveRecord 很赞啊
@slene ,ok !
@slene 用Raw()这种形式,我好忧伤。特别是要考虑顺序。因为我的字段都已经按照ORM的规则编写的,那么,也可以通过其推导出我要取的字段。so.....我该怎么破不考虑字段顺序的问题。其实,那个IN里面的问号的问题,都没有这个紧迫。
之前主要是考虑到这种功能,就做成那个样了。使用临时的 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)"`
}
@slene ,我认为这个功能应该不常用,可以砍掉这个功能
@phpqinsir 认为如何
@slene 对的。可以砍掉。因为,在QueryRows里面传递两个对象真心没用到啊。也没有那种需求。我在PHP框架里面也没有遇到过这种ORM。所以,可以去掉的。谢谢噢。
OK 改进
@slene PHP的orm库,我用过Doctrine2,本身代码复杂度太高了.
自定义了一个dql查询语言,比较鸡肋,一般使用QueryBuilder.
@slene 也可以参考下 java 的 Nutz 框架中的 Dao,也很简单方便。它有一个从单独文件中加载sql的功能,可以将sql语句从代码中剥离出来,维护起来非常很爽。
这个问题本身不是很复杂.
只需要先把数据库的查询结果变成一个[]map[string]string,再把数据填回用户输入的结构体里面就好了..
此处代码可以把数据库的查询结果变成一个[]map[string]string
https://github.com/bronze1man/kmg/blob/master/kmgSql/QueryGrid.go
用惯了Rails的ActiveRecord后再看Beego的,感觉相当的不便利。不奢望能在查询时返回ActiveRecord::Relation,但是至少能有ActiveRecord::Base里定义好的那么多便利的方法呀。
raw sql的功能建议可以参考一下mybatis的实现方式。
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方法?!
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也弄到呢?
@winerQin Thank you for supporting beego. please update or submit your issue in English for a better international user friendly communication.
oracle数据库,占位符不是“?” 是 “:序号“
Most helpful comment
@winerQin Thank you for supporting beego. please update or submit your issue in English for a better international user friendly communication.