forked from mirror/gorm
3.3 KiB
3.3 KiB
Advanced Usage
Error Handling
query := db.Where("name = ?", "jinzhu").First(&user)
query := db.First(&user).Limit(10).Find(&users)
// query.Error will return the last happened error
// So you could do error handing in your application like this:
if err := db.Where("name = ?", "jinzhu").First(&user).Error; err != nil {
// error handling...
}
// RecordNotFound
// If no record found when you query data, gorm will return RecordNotFound error, you could check it like this:
db.Where("name = ?", "hello world").First(&User{}).Error == gorm.RecordNotFound
// Or use the shortcut method
db.Where("name = ?", "hello world").First(&user).RecordNotFound()
if db.Model(&user).Related(&credit_card).RecordNotFound() {
// no credit card found error handling
}
Transactions
To perform a set of operations within a transaction, the general flow is as below.
The database handle returned from db.Begin()
should be used for all operations within the transaction.
(Note that all individual save and delete operations are run in a transaction by default.)
// begin
tx := db.Begin()
// do some database operations (use 'tx' from this point, not 'db')
tx.Create(...)
...
// rollback in case of error
tx.Rollback()
// Or commit if all is ok
tx.Commit()
A Specific Example
func CreateAnimals(db *gorm.DB) err {
tx := db.Begin()
// Note the use of tx as the database handle once you are within a transaction
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
Raw SQL
db.Exec("DROP TABLE users;")
db.Exec("UPDATE orders SET shipped_at=? WHERE id IN (?)", time.Now, []int64{11,22,33})
Row & Rows
It is even possible to get query result as *sql.Row
or *sql.Rows
row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)
row.Scan(&name, &age)
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
defer rows.Close()
for rows.Next() {
...
rows.Scan(&name, &age, &email)
...
}
// Raw SQL
rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)
defer rows.Close()
for rows.Next() {
...
rows.Scan(&name, &age, &email)
...
}
Scan Rows
rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
defer rows.Close()
for rows.Next() {
var user User
db.ScanRows(rows, &user)
// do something
}
Composite Primary Key
type Product struct {
ID string `gorm:"primary_key"`
LanguageCode string `gorm:"primary_key"`
}
Logger
Gorm has built-in logger support
// Enable Logger
db.LogMode(true)
// Diable Logger
db.LogMode(false)
// Debug a single operation
db.Debug().Where("name = ?", "jinzhu").First(&User{})
Customize Logger
// Refer gorm's default logger for how to: https://github.com/jinzhu/gorm/blob/master/logger.go#files
db.SetLogger(gorm.Logger{revel.TRACE})
db.SetLogger(log.New(os.Stdout, "\r\n", 0))