Database Programming with Go and GORM

Cihan Ozhan
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

--

--