GORM is a powerful and easy-to-use object-relational mapping (ORM) library for Go (Golang). It provides a high-level, flexible, and customizable interface to interact with various databases while adhering to Go’s idiomatic and concurrent programming style. In this article, we’ll discuss how to use GORM in your Go projects, covering installation, basic CRUD operations, and advanced features.
To install GORM, use the go get
command:
go get -u gorm.io/gorm
GORM supports several databases, including PostgreSQL, MySQL, SQLite, and SQL Server. For this tutorial, we’ll use SQLite. Install the SQLite driver by running:
go get -u gorm.io/driver/sqlite
Now, let’s import the necessary packages and configure GORM to use SQLite:
package main
import (
"gorm.io/gorm"
"gorm.io/driver/sqlite"
)
func main() {
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
if err != nil {
panic("failed to connect to database")
}
}
In GORM, you define models as Go structs with annotations to map them to the database schema. For example, let’s create a User
model:
type User struct {
ID uint `gorm:"primaryKey"`
FirstName string `gorm:"size:64"`
LastName string `gorm:"size:64"`
Email string `gorm:"uniqueIndex;size:128"`
Age int
}
The gorm
tags define the column constraints and indexes. In this case, we’ve set primary key, size, and unique index constraints.
To insert a new record, create an instance of the model, and use the Create
method:
user := User{FirstName: "John", LastName: "Doe", Email: "john.doe@example.com", Age: 30}
result := db.Create(&user)
if result.Error != nil {
panic("failed to create user")
}
You can retrieve records using various query methods supported by GORM. Some examples are:
First
: Fetch the first record matching the conditionsFind
: Fetch all records matching the conditionsTake
: Fetch one record matching the conditions// Find a user by primary key
var user User
db.First(&user, 1)
// Find users with age greater than 25
var users []User
db.Where("age > ?", 25).Find(&users)
To update a record, you can use the Save
method, which updates all fields, or the Updates
method, which updates only non-zero fields:
// Update a single field
db.Model(&user).Update("age", 35)
// Update multiple fields
db.Model(&user).Updates(User{FirstName: "Johnathan", LastName: "Smith"})
// Update only non-zero fields
db.Model(&user).Updates(map[string]interface{}{"FirstName": "Johnathan", "LastName": "Smith"})
To delete a record, use the Delete
method:
db.Delete(&user)
GORM supports associations like Has One
, Has Many
, Belongs To
, and Many-to-Many
. For example, let’s create User
and Post
models with a one-to-many relationship:
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:64"`
Posts []Post
}
type Post struct {
ID uint `gorm:"primaryKey"`
Title string `gorm:"size:128"`
Body string `gorm:"type:text"`
UserID uint
}
To create a new post and associate it with a user, you can do the following:
post := Post{Title: "My first post", Body: "This is the content of my first post."}
db.Model(&user).Association("Posts").Append(&post)
GORM provides a simple way to create and modify the database schema using migrations. To create the schema for your models, use the AutoMigrate
method:
db.AutoMigrate(&User{}, &Post{})
GORM will automatically create tables and columns based on your model definitions. If you change a model’s schema, you can run AutoMigrate
again to apply the changes. However, note that GORM doesn’t support migrating column data types or deleting columns.
In this article, we’ve introduced GORM, a powerful ORM library for Go, and demonstrated how to perform basic CRUD operations, work with associations, and manage migrations. GORM provides many advanced features, such as transactions, hooks, scopes, and query builders, which can be explored further in the official documentation.
By leveraging GORM in your Go projects, you can achieve a cleaner, more maintainable, and more idiomatic codebase for interacting with databases.