英文:
How to modify GORM DB pointer in function?
问题
我有一个用Go编写的REST API应用程序,它使用GORM作为ORM。在重构某些部分时,我想将一些常见操作移动到一个外部函数ApplyToDBQuery(query *gorm.DB)
中,该函数接受一个指向DB查询的指针并对其进行修改,以便稍后可以使用修改后的查询。
示例用法:
query = shared.DB.Debug()
req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) {
query.Limit(...)
query.Offset(...)
query.Where(...)
}
我认为,由于我传递了一个指针给函数,原始查询应该已经被修改了,但实际上原始查询并没有发生任何变化。
我还尝试过传递指向指针的指针ApplyToDBQuery(query **gorm.DB)
,返回修改后的指针ApplyToDBQuery(query *gorm.DB) *gorm.DB
,甚至是这两者的组合 - ApplyToDBQuery(query **gorm.DB) *gorm.DB
,但由于想法不足,都没有成功。
英文:
I have a REST API application written in Go, which uses GORM as ORM. During refactoring of some parts, I wanted to move some common operations to an external function ApplyToDBQuery(query *gorm.DB)
, which takes a pointer to the DB query and modifies it, so that the modified query can be used later.
Example usage:
query = shared.DB.Debug()
req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) {
query.Limit(...)
query.Offset(...)
query.Where(...)
}
I thought, that since I'm passing a pointer to the function, the original query should've been modified, but nothing really happened to the original query.
I've also tried passing a pointer to pointer ApplyToDBQuery(query **gorm.DB)
, returning the modified pointer ApplyToDBQuery(query *gorm.DB) *gorm.DB
and out of lack of ideas, even a combination of these two - ApplyToDBQuery(query **gorm.DB) *gorm.DB
答案1
得分: 2
Gorm对象在每次操作时都会克隆自身,因此原始指向的值永远不会改变。
你应该返回最新版本的gorm.DB:
return query.Limit(...).Offset(...).Where(...)
英文:
Gorm object clone itself for every operation, therefore the original pointed value is never changed.
You should return the latest version of gorm.DB:
return query.Limit(...).Offset(...).Where(...)
答案2
得分: 1
将方法接收器更改为:
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) *gorm.DB {
return query.Limit(...).
Offset(...).
Where(...)
}
然后将其用作:
query = req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
原因已经由 @R3v4n 指出。
英文:
Change the method receiver to
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) *gorm.DB {
return query.Limit(...).
Offset(...).
Where(...)
}
then use it as:
query = req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
The reason is already pointed by @R3v4n
答案3
得分: 1
你应该按照前两个答案的建议去做,但是如果由于某种原因,你必须对传入的指针进行更改,你仍然可以通过"手动"的方式来实现。
query = shared.DB.Debug()
req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
func (r *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) {
q := query.Limit(...).Offset(...).Where(...)
*query = *q
}
另外,一点注意事项是,通常不建议使用this
和self
这样的接收者名称,而是更倾向于使用类型名称的简短缩写,比如使用1到3个字母。
例如:
func (r *Request) AddCookie(c *Cookie)
func (c *Client) Get(url string) (resp *Response, err error)
func (srv *Server) ListenAndServe() error
英文:
You should go with what the previous two answers recommend, but, if for some reason, you have to apply changes to the passed in pointer, you can still do it "manually".
query = shared.DB.Debug()
req.ApplytoDBQuery(query)
if query.find(&data).Error != nil {...}
func (r *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) {
q := query.Limit(...).Offset(...).Where(...)
*query = *q
}
As a side note, it is generally discouraged to use receiver names like this
and self
, instead the preferred way is to use a short, let's say 1 to 3 letters, abbreviation of the type's name.
For example:
func (r *Request) AddCookie(c *Cookie)
func (c *Client) Get(url string) (resp *Response, err error)
func (srv *Server) ListenAndServe() error
答案4
得分: 0
补充 @R3v4n 的回答:
- 使用链式调用
- 使用
db.Scopes
来重用代码,而不是常规的函数调用。
可以像这样:
query = shared.DB.Debug()
if query.Scopes(req.ApplyToDBQuery).find(&data).Error != nil {
// 处理错误
}
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) *gorm.DB {
return query.Where(...).Limit(...).Offset(...)
}
英文:
Complementing @R3v4n answer:
- Use chaining
- Use
db.Scopes
for code reusage instead of usual func calls.
It can be like this:
query = shared.DB.Debug()
if query.Scopes(req.ApplyToDBQuery).find(&data).Error != nil {
// handle error
}
func (this *MyCustomRequest) ApplyToDBQuery(query *gorm.DB) *gorm.DB {
return query.Where(...).Limit(...).Offset(...)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论