1. ORM là gì?

Trước hết để hiểu được thư viện Gorm chúng ta cần tìm hiểu về ORM, một công cụ quan trọng và thường xuyên được áp dụng trong quản trị cơ sở dữ liệu.
ORM là tên viết tắt của cụm từ “Object Relational Mapping” đây là tên gọi chỉ việc ánh xạ các record dữ liệu trong hệ quản trị cơ sở dữ liệu sang dạng đối tượng mà mã nguồn đang định nghĩa trong class. Là một khái niệm phổ biến, được cài đặt trong tất cả các loại ngôn ngữ hiện đại ngày nay như: java, php, node.js, swift … Bạn dễ dàng có thể cài đặt ORM hoặc sử dụng các thư viện mã nguồn mở về ORM trong bất cứ dự án nào bạn thích.
Với một ngôn ngữ lập trình phía backend làm việc nhiều với cơ sở dữ liệu như Golang thì cũng không ngoại lệ. Chính vì vậy GORM ra đời để phục vụ cho các Dev như chúng ta.

2. GORM là gì?

GORM là thư viện ORM tuyệt vời cho Golang. Nó là một thư viện ORM để xử lý với quan hệ cơ sở dữ liệu. Thư viện Gorm này được phát triển trên các package cơ sở dữ liệu/SQL.
Tổng quan và tính năng của GORM là:

  • Full-Featured ORM (almost)
  • Associations (Has One, Has Many, Belongs To, Many Too Many, Polymorphism)
  • Callbacks (Before/After Create/Save/Update/Delete/Find)
  • Preloading (eager loading)
  • Transactions
  • Composite Primary Key
  • SQL Builder
  • Logger
  • Developer Friendly

3. Cài đặt GORM, kết nối đến database

Yêu cầu để cài đặt gorm máy bạn cần cài đặt Golang nhé.
sau đó chỉ cần sử dụng command đơn giản như sau:

go get -u github.com/jinzhu/gorm

Trong bài viết này mình sẽ hướng dẫn bạn làm việc với MySQL, một cơ sở dữ liệu mà hầu hết chúng ta đều biết.
Để sử dụng, chỉ cần nhập package này vào dự án của bạn cùng với database drivers như bạn muốn

import (
  "github.com/jinzhu/gorm"
  "github.com/go-sql-driver/mysql"
  "github.com/jinzhu/gorm/dialects/mysql"
)

Bây giờ sử dụng gorm để thực hiện các hoạt động trên cơ sở dữ liệu.
Để kết nối với cơ sở dữ liệu, chỉ cần sử dụng cú pháp sau.

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/mysql"
)

func main() {
  db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
  if err != nil {
    panic("failed to connect database") // Kiểm tra kết nối tới database
  }
  defer db.Close() // Để đóng cơ sở dữ liệu khi nó không được sử dụng
}

Nếu hoàn thành bước này, chúc mừng bạn đã đặt chân đầu tiên vào thư viện Gorm nhé.

4. Tạo Models và Tables

Các Model thường chỉ là các struct trong Golang bình thường, các type cơ bản hoặc các pointers.Mình sẽ hướng dẫn các bạn tạo một Model User cơ bản và tạo Table từ Model User như sau.

type User struct {
    ID int
    Username string
}

func main() {
    // Sau khi kết nối tới database ta tạo bảng bằng lệnh CreateTable()
    db.CreateTable(&User{})
    
    db.hasTable(&User{}) // Kiểm tra table có được tạo thành công hay không
    db.DropTableIf Exists(&User{}) // Drops table nếu table có tồn tại
}

ngoài ra bạn có thể tạo table bằng Auto Migration, tính năng này sẽ tự động tạo bảng dựa trên mô hình của bạn mà không phải tạo bảng theo cách thủ công. Gorm cũng đưa ra định nghĩa model bao gồm các trường như Id, CreatedAt, UpdatedAt, DeletedAt. Nếu bạn muốn sử dụng chỉ cần nhúng gorm.Model trong model/struct của bạn. ví dụ như sau

// thêm các trường `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt` vào model `User`
type User struct {
  gorm.Model
  Username string
}

Trong Gorm, trường ID được tự động đặt thành Primary key với thuộc tính auto increment.

5. CRUD trong GORM

CRUD là bốn chức năng cơ bản (Create, Read/Query, Update, và Delete) của model. Vì là thư viện dành cho quản lý cơ sở dữ liệu nên CRUD đương nhiên là sẽ tích hợp sẵn trong gorm mình cùng điểm qua và học cách làm việc bằng CRUD với GORM nhé.

Create/Insert

Để Create/Insert một record, bạn cần sử dụng hàm Create().
Ví dụ như sau:

// Ta định nghĩa Model Animal như dưới đây
type Animal struct {
  ID   int64
  Name string
  Age  int64
}

var animal = Animal{Age: 14, Name: "Lion"}
db.Create(&animal)
// INSERT INTO animals("age") values('14');
// SELECT name from animals WHERE ID=111;
// animal.Name => 'Lion'

Query

Để truy vấn dữ liệu trong database ta có thể sử dụng nhiều cách như sau:

// lấy ra record đầu tiên, order là primary key
db.First(&user)
//// SELECT * FROM users ORDER BY id LIMIT 1;

// lấy ra một record không order
db.Take(&user)
//// SELECT * FROM users LIMIT 1;

// lấy ra record cuối, order là primary key
db.Last(&user)
//// SELECT * FROM users ORDER BY id DESC LIMIT 1;

// lấy hết tất cả record
db.Find(&users)
//// SELECT * FROM users;

// Lấy record bằng primary key
db.First(&user, 10)
//// SELECT * FROM users WHERE id = 10;

Ngoài ra ta cũng có thể truy vấn dữ liệu sử dụng cú pháp db.Where()

db.Where("name = ?", "jinzhu").First(&user)
//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;

db.Where("name = ?", "jinzhu").Find(&users)
//// SELECT * FROM users WHERE name = 'jinzhu';

// <>
db.Where("name <> ?", "jinzhu").Find(&users)

// IN
db.Where("name IN (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)

// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)

// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)

// Time
db.Where("updated_at > ?", lastWeek).Find(&users)

// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)

Còn nhiều cách truy vấn dựa vào GORM nữa nên muốn biết thêm bạn có thể vào link này.Gorm-query.

Update

Sử dụng hàm save() để update dữ liệu trong table.
Ví dụ như sau:

db.First(&animal) // Query dữ liệu trong bảng animal

animal.Name = "Tiger"
animal.Age = 20
db.Save(&animal) // lưu lại dữ liệu thông qua hàm save

Delete

Sử dụng cú pháp đơn giản như sau db.Delete():

db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
//// DELETE from emails where email LIKE "%jinzhu%";

db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
//// DELETE from emails where email LIKE "%jinzhu%";

6. Asociations

Các Asociation hay quan hệ giữa các struct hoặc các model tương tác với nhau. Vì vậy, đối với điều này, bạn cần tạo/xác định loại mối quan hệ ở cả hai đầu.

Belongs To

Mối quan hệ One to One chỉ định cách các trường của model có liên quan với nhau bằng cách chỉ định ánh xạ One to One.1Belongs to là một thiết lập one-to-one connection với một model khác, sao cho mỗi instance của model khai báo, thuộc về một instance của mô hình kia.
Ví dụ có 2 model User và Profile, một User chỉ có một Profile và một Profile chỉ có một User, đó là quan hệ One to One.

type User struct {
  gorm.Model
  Name string
}

// `Profile` belongs to `User`, `UserID` is the foreign key
type Profile struct {
  gorm.Model
  UserID int
  User   User
  Name   string
}

Để định nghĩa khóa ngoại ta có thể dùng như sau:

type User struct {
  gorm.Model
  Refer string
  Name string
}

type Profile struct {
  gorm.Model
  Name      string
  User      User `gorm:"association_foreignkey:Refer"` // use Refer as association foreign key
  UserRefer string
}

Has One

Ví dụ như nếu ứng dụng của bạn bao gồm userscredit_cards và mỗi user chỉ có thể có một credit card:

type User struct {
  gorm.Model
  Name string
}

// `Profile` belongs to `User`, `UserID` is the foreign key
type Profile struct {
  gorm.Model
  UserID int
  User   User
  Name   string
}

Has Many

Một model được thiết lập kết nối one-to-many với một model khác.
Ví dụ như nếu ứng dụng của bạn bao gồm userscredit_cards và mỗi user có thể có nhiều credit card chẳng hạn.

type User struct {
  gorm.Model
  CreditCards []CreditCard
}

type CreditCard struct {
  gorm.Model
  Number   string
  UserID  uint
}

Many To Many

Many to Many sẽ join một table giữa hai model.

Ví dụ: nếu ứng dụng của bạn bao gồm users và languagesusers có thể nói nhiều languages và nhiều users có thể nói một languages cụ thể.

type User struct {
  gorm.Model
  Languages         []Language `gorm:"many2many:user_languages;"`
}

type Language struct {
  gorm.Model
  Name string
}

7. KẾT LUẬN

Trên đây mình đã tổng hợp một số kiến thức cơ bản về GORM cũng như một vài tính năng cơ bản của GORM cho các bạn. Ngoài những điều mình vừa viết GORM còn nhiều ứng dụng tính năng hay ho nữa như:Transactions, Preloading(Eager Loading), hay các Conventions... Dễ dàng cho bạn làm việc với cơ sở dữ liệu hơn. Hy vọng qua Blog này các bạn có thể hiểu rõ hơn một chút về GOLANG đặc biệt là thư viện GORM nhé.

8. Link tham khảo

http://gorm.io/