Database Programming with Go and GORM
5 min readNov 8, 2021
Database Programming with Go and GORM
I wrote this code in 2016 but re-shared it for newbies.
Hi everyone!
I wrote a few articles on database programming with Go. In this article series I will tell you a Go framework; GORM!
What is GORM?
According to the developer’s description; “The fantastic ORM library for Golang, aims to be developer friendly.”
GORM is a Go ORM framework!
Links
How to use GORM?
It is very easy…
GORM installation;
- go get -u github.com/jinzhu/gorm (for GORM installation)
- go get -u github.com/lib/pq (for using Postgres, we install the ‘pq’ library)
That’s it! Now let’s write some code…
Database Connection with GORM
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=postgres password=1234567 dbname=postgres sslmode=disable")
if err != nil {
panic(err.Error())
}
// Close the connection when the database transaction is over.
defer db.Close() // Not required!
// Get the object instance of the database.
dbase := db.DB()
// Close the connection when the database transaction is over.
defer dbase.Close() // The 'dbase' object is an instance a 'db' object.
// We are pinging through 'dbase'.
err = dbase.Ping()
if err != nil {
// Is there an error?
panic(err.Error())
}
println("Connection to database established.")
}
It there are no errors; Connection to database established.
Create a New Table
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.CreateTable(&User{})
println("Connection to database established.")
}
type User struct {
ID uint
Username string
FirstName string
LastName string
}
Add Data with Data Object
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{}) // Delete old table if it exists.
db.CreateTable(&User{}) // Create a new table.
// Create object for object data.
user := User{
Username: "cihanozhan",
FirstName: "Cihan",
LastName: "Özhan",
}
// Add(Create) data
db.Create(&user)
fmt.Println(user)
println("done.")
}
type User struct {
ID uint
Username string
FirstName string
LastName string
}
Bring The First & Last Data
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB
sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
// Save the list of users the database
for _, user := range users {
db.Create(&user)
}
u := User{}
db.First(&u) // Bring the first data
// db.Last(&u) // Bring the end data
fmt.Println(u)
println("done.")
}
type User struct {
ID uint
Username string
FirstName string
LastName string
}
var users []User = []User{
User{Username: "mzuckerberg", FirstName: "Mark", LastName: "Zuckerberg"},
User{Username: "bgates", FirstName: "Bill", LastName: "Gates"},
User{Username: "sjobs", FirstName: "Steve", LastName: "Jobs"},
User{Username: "lellison", FirstName: "Larry", LastName: "Ellison"},
}
Where Filter & Update(Save) Data
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
for _, user := range users {
db.Create(&user)
}
u := User{Username: "cozhan"} // Data to be used in the filter
db.Where(&u).First(&u) // Use the above data as a filter
fmt.Println(u)
u.LastName = "Özhan" // Replace with this data
db.Save(&u) // Replace and save
user := User{}
db.Where(&u).First(&user) // Bring the first data
fmt.Println(user)
}
type User struct {
ID uint
Username string
FirstName string
LastName string
}
var users []User = []User{
User{Username: "mzuckerberg", FirstName: "Mark", LastName: "Zuckerberg"},
User{Username: "bgates", FirstName: "Bill", LastName: "Gates"},
User{Username: "sjobs", FirstName: "Steve", LastName: "Jobs"},
User{Username: "lellison", FirstName: "Larry", LastName: "Ellison"},
User{Username: "cozhan", FirstName: "Cihan", LastName: "Öz"},
}
Where Filter & Delete Data
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
for _, user := range users {
db.Create(&user)
}
// Delete incoming data with filter
db.Where(&User{Username: "cozhan"}).Delete(&User{})
fmt.Println("done.")
}
type User struct {
ID uint
Username string
FirstName string
LastName string
}
var users []User = []User{
User{Username: "mzuckerberg", FirstName: "Mark", LastName: "Zuckerberg"},
User{Username: "bgates", FirstName: "Bill", LastName: "Gates"},
User{Username: "sjobs", FirstName: "Steve", LastName: "Jobs"},
User{Username: "lellison", FirstName: "Larry", LastName: "Ellison"},
User{Username: "cozhan", FirstName: "Cihan", LastName: "Özhan"},
}
Creating a New Table with a Different Name
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
}
// The name of the new table will not be 'user'
type User struct {
ID int
Username string
FirstName string
LastName string
}
// Change the name of the table created automatically with the struct.
func (u User) TableName() string {
return "OldUsers" // New table's real name
}
Creates Constraing with GORM
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.DropTable(&Category{})
db.CreateTable(&User{})
db.CreateTable(&Category{})
}
type Category struct {
// Automatically includes id, createdAt, updatedAt, deletedAt objects.
gorm.Model
}
type User struct {
// GORM doesn't like 'id'. Should be 'ID'.
ID int
// Creates a primary key for UserID.
UserID int `gorm:"primary_key"`
// Creates constrains for Username
// -> 15 character max limit and not be passed a the blank
Username string `sql:"type:VARCHAR(15);not null"`
// Creates constraints for FirstName
// -> 100 character max limit, Not be passed a the blank, Column name will not be FName, will be FirstName
FName string `sql:"size:100;not null" gorm:"column:FirstName"`
// Creates consstraints for LastName
// -> Unique index/constraint, Not be passed a the blank, Default value is 'Unknown', Column name will not be LName, will be LastName
LName string `sql:"unique;unique_index;not null;DEFAULT:'Unknown'" gorm:"column:LastName"`
Count int `gorm:"AUTO_INCREMENT"`
TempField bool `sql:"-"` // Ignore a Field
}
Using an Embedded Property
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/lib/pq"
)
func main() {
db, err := gorm.Open("postgres", "user=co password=1234567 dbname=ecommerceDB sslmode=disable")
if err != nil {
panic(err.Error())
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
// Bring up(with Reflection) the fieds in the User object.
for _, f := range db.NewScope(&User{}).Fields() {
println(f.Name)
}
}
type User struct {
Model gorm.Model //`gorm:"embedded"` // <- When this field is active, the date and ID objects are activated.
FirstName string
LastName string
}
Good luck!
Cihan Özhan