CRUD Operations
Create, read, update, and delete database records with Velocity ORM's fluent API.
Create, read, update, and delete records with Velocity ORM.
Create
Save Instance
user := User{
Name: "John Doe",
Email: "john@example.com",
Role: "user",
}
err := user.Save() // Creates new record
fmt.Printf("User created with ID: %d\n", user.ID)Create with Map
user, err := User{}.Create(map[string]any{
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin",
})Create Multiple
users := []User{
{Name: "Alice", Email: "alice@example.com"},
{Name: "Bob", Email: "bob@example.com"},
}
err := User{}.CreateMany(users)First Or Create
Find or create if not exists:
// Find by email, or create with provided attributes
user, created := User{}.FirstOrCreate(
map[string]any{"email": "john@example.com"}, // Search criteria
map[string]any{"name": "John Doe", "role": "user"}, // Creation attributes
)
if created {
fmt.Println("New user created")
} else {
fmt.Println("Existing user found")
}Update Or Create
Find and update, or create if not exists:
user, err := User{}.UpdateOrCreate(
map[string]any{"email": "john@example.com"}, // Search criteria
map[string]any{"name": "John Updated", "role": "admin"}, // Update/create attributes
)Read
See Query Builder for detailed query documentation.
// Find by ID
user, err := User{}.Find(1)
// Find by field
user, err := User{}.FindBy("email", "john@example.com")
// First/Last
user, err := User{}.First()
user, err := User{}.Last()
// All records
users, err := User{}.All()
// With conditions
users, err := User{}.Where("role = ?", "admin").Get()Update
Update Instance
user, _ := User{}.Find(1)
user.Name = "Updated Name"
user.Email = "newemail@example.com"
err := user.Save() // Updates existing record (has ID)Update with Map
user, _ := User{}.Find(1)
err := user.Update(map[string]any{
"role": "admin",
"active": true,
})Mass Update
// Update single field
affected := User{}.Where("role = ?", "guest").Update("active", false)
// Update multiple fields
affected := User{}.WhereRole("guest").UpdateMany(map[string]any{
"active": false,
"role": "user",
})
fmt.Printf("Updated %d records\n", affected)Increment / Decrement
user, _ := User{}.Find(1)
// Increment by 1
user.Increment("login_count")
// Increment by specific amount
user.Increment("points", 100)
// Decrement
user.Decrement("credits", 10)
// Mass increment
User{}.Where("active = ?", true).Increment("bonus", 5)Touch Timestamps
user, _ := User{}.Find(1)
// Update updated_at to current time
user.Touch()
// Touch related records
user.Posts().Touch()Delete
Soft Delete
If your model has a DeletedAt field, records are soft deleted:
type User struct {
orm.Model[User]
Name string `orm:"column:name"`
DeletedAt *time.Time `orm:"column:deleted_at"` // Enables soft delete
}
user, _ := User{}.Find(1)
err := user.Delete() // Sets deleted_at, doesn't remove rowForce Delete
Permanently remove records:
user, _ := User{}.Find(1)
err := user.ForceDelete() // Permanent deletionMass Delete
// Delete matching records
affected := User{}.Where("role = ?", "guest").Delete()
// Force delete matching records
affected := User{}.Where("active = ?", false).ForceDelete()Delete with Associations
user, _ := User{}.Find(1)
// Delete user and related records
user.DeleteWith("Profile", "Posts")Working with Soft Deletes
Query Soft Deleted Records
// Only soft deleted records
users, _ := User{}.OnlyTrashed().Get()
// Include soft deleted records
users, _ := User{}.WithTrashed().Get()
// Normal query (excludes soft deleted)
users, _ := User{}.Get()Restore Soft Deleted Records
user, _ := User{}.OnlyTrashed().Find(1)
err := user.Restore()
// Mass restore
User{}.OnlyTrashed().Where("role = ?", "admin").Restore()Check if Soft Deleted
user, _ := User{}.WithTrashed().Find(1)
if user.Trashed() {
fmt.Println("User is soft deleted")
}Transactions
Callback Transaction
err := orm.Transaction(func() error {
user := User{Name: "John", Email: "john@example.com"}
if err := user.Save(); err != nil {
return err // Auto rollback
}
profile := Profile{UserID: user.ID, Bio: "Developer"}
if err := profile.Save(); err != nil {
return err // Auto rollback
}
return nil // Auto commit
})
if err != nil {
log.Printf("Transaction failed: %v", err)
}Manual Transaction
tx := orm.Begin()
defer tx.Rollback() // Rollback if not committed
user := User{Name: "Jane"}
if err := user.SaveTx(tx); err != nil {
return err
}
profile := Profile{UserID: user.ID}
if err := profile.SaveTx(tx); err != nil {
return err
}
if err := tx.Commit(); err != nil {
return err
}Nested Transactions (Savepoints)
err := orm.Transaction(func() error {
user := User{Name: "John"}
user.Save()
// Nested transaction (savepoint)
err := orm.Transaction(func() error {
post := Post{UserID: user.ID, Title: "Draft"}
return post.Save()
})
if err != nil {
// Inner transaction rolled back, outer continues
log.Printf("Failed to create post: %v", err)
}
return nil
})Model Events
type User struct {
orm.Model[User]
Name string `orm:"column:name"`
Email string `orm:"column:email"`
}
// Before create
func (u *User) Creating() error {
u.Email = strings.ToLower(u.Email)
return nil
}
// After create
func (u *User) Created() {
log.Printf("User %d created", u.ID)
}
// Before update
func (u *User) Updating() error {
return nil
}
// After update
func (u *User) Updated() {
log.Printf("User %d updated", u.ID)
}
// Before delete
func (u *User) Deleting() error {
return nil
}
// After delete
func (u *User) Deleted() {
log.Printf("User %d deleted", u.ID)
}Best Practices
- Use transactions - Wrap related operations in transactions
- Prefer soft deletes - Use soft deletes for recoverable data
- Validate before save - Validate data in
Creating()/Updating()hooks - Handle errors - Always check returned errors
- Use mass updates carefully - Mass updates skip model events
- Index for performance - Index columns used in WHERE clauses
