Traps for manipulating MySQL using XORM
Although using ORM to operate MySQL is more convenient than directly using the standard library `sql`[1] and the three-party MySQL database driver package [2], it will also encounter some pitfalls.
Type zero value
In Golang, each data type has its own type zero value, for example, the zero value of int is0
, the zero value of string is''
wait.
Sample code:
package main import ( "fmt" _ "/go-sql-driver/mysql" "/xorm" ) func main() { // Create Engine engine, err := ("mysql", "root:root@/example?charset=utf8") defer func() { err = () if err != nil { ("engine close err=%v\n", err) return } }() if err != nil { ("init xorm engine fail, err=%v\n", err) return } // Update data example := &Example{ Title: "go", View: 0, } condi := &Example{ Id: 2, } affected, err := (example, condi) if err != nil { ("Update err=%v\n", err) return } ("affected=%d\n", affected) } type Example struct { Id int `json:"id" form:"id"` Title string `json:"title" form:"title"` View int `json:"view" form:"view"` Created int `json:"created" form:"created" xorm:"created"` Updated int `json:"updated" form:"updated" xorm:"updated"` }
Read the above code and we can find that the example code willid=2
The data view field is updated to0
,because0
is the type zero value of int, and the Update method of XORM will automatically ignore the type zero value, so the value of the view field of this data has not changed.
However, in actual project development, we may need to update the value of a certain field to the type zero value of the field type. How should we do it at this time?
affected, err := ("title", "view").Update(example, condi)
We can useCols()
Method, specify the field that needs to be updated, so that even if the value of the field that needs to be updated is the zero value of the field type, it can be changed normally.
Tip: It is recommended that when designing database tables, try to use non-type zero values for the field values.
Self-increasing id
When inserting data, we may need to return the autoincrement id. Let's first look at a piece of code:
// Insert dataexample := &Example{ Title: "PHP", View: 90, } affected, err := (example) if err != nil { ("Insert err=%v\n", err) return } ("affected=%v\n", affected)
Reading the above code, we insert a piece of data, and the result returns affects the number of rows and error information, rather than directly returning the self-increment id of the piece of data.
Some readers may then use the query method to query the id of the latest data. In scenarios with low concurrent requests, this method can find the self-increment id of the newly inserted data.
However, in scenarios with high concurrent requests, the id of the latest data found by this method may not be the auto-increment id of the data we just inserted.
id := ("affected=%v || id=%d\n", affected, id)
Read the above code, we want to obtain the self-increment id of the newly inserted data, and directlyYou can get it, butPrerequisitesIt is in the structure,
id
Field usagexorm:"autoincr"
Label.
Update created fields
We use labels in structurexorm:created
andxorm:updated
It can automatically insert the current time.
However, usexorm:created
The field of the tag is written to the current time only when the data is inserted for the first time and will no longer be changed after that; usexorm:updated
The field of the label is written to the current time when the data is inserted for the first time. The time will change every time the Update operation thereafter.
If our business needs are to be changed, usexorm:created
Can the fields of the tag be done?
// Change the dataexample := &Example{ Title: "JavaScript", View: 98, } condi := &Example{ Id: 2, } affected, err := (example, condi) if err != nil { ("Update err=%v\n", err) return } ("affected=%d\n", affected)
Reading the above code, we found that after executing the Update method, usexorm:updated
The value of the field of the tag is changed, and the value of the field is changed, and the value of the field is usedxorm:created
The value of the field of the label has not been changed.
Let's change the way to update the data, the code is as follows:
// Change the datasql := "UPDATE example SET title=?, view=?, created=? WHERE id=?" res, err := (sql, "Python", 60, ().Unix(), 2) if err != nil { ("Update err=%v\n", err) return } affected, err := () if err != nil { ("RowsAffected err=%v\n", err) return } ("affected=%d\n", affected)
Reading the above code, we can find that using the Exec method to execute native SQL can meet our needs.
Summarize
In this article, we have introduced the traps that novices may encounter when using XORM to operate MySQL. I hope it can bring some help to you. For more information about Go XORM to operate MySQL, please pay attention to my other related articles!