Điều kiện cần
- Đã biết cài đặt môi trường phát triển và lập trình căn bản với Golang
- Đã biết cài đặt và sử dụng CSDL MySQL
- Có hiểu biết về hệ quản trị CSDL Quan hệ và biết cách sử dụng SQL để thao tác với dữ liệu
- Biết cách thức kết nối Golang với CSDL MySQL
Các thao tác CRUD
Trong lập trình máy tính, CRUD là viết tắt của Create Read Update Delete (Tạo, Đọc/Truy xuất, Cập nhật, Xoá) là bốn chức năng cơ bản của lưu trữ liên tục. Các từ thay thế đôi khi được sử dụng khi xác định bốn chức năng cơ bản của CRUD, chẳng hạn như truy xuất thay vì đọc, sửa đổi thay vì cập nhật hoặc hủy thay vì xóa. CRUD đôi khi cũng được sử dụng để mô tả các quy ước giao diện người dùng tạo điều kiện thuận lợi cho việc xem, tìm kiếm và thay đổi thông tin, thường sử dụng các biểu mẫu và báo cáo dựa trên máy tính.
Thuật ngữ này được phổ biến lần đầu tiên bởi James Martin trong cuốn sách "Managing the Data-base Environment" (Quản lý Môi trường Cơ sở Dữ liệu) năm 1983 của ông.
Từ viết tắt này có thể được mở rộng thành CRUDL để bao gồm danh sách các tập dữ liệu lớn mang lại sự phức tạp hơn như phân trang khi các tập dữ liệu quá lớn để có thể dễ dàng lưu giữ trong bộ nhớ.
Chuẩn bị CSDL trong MySQL
Trước tiên cần cài đặt CSDL MySQL và có tài khoản root
và mật khẩu để đăng nhập vào trong MySQL.
Tải tệp OrderDB.sql với liên kết tại đây.
Chạy file OrderDB.sql
bằng lệnh sau:
mysql -u root -p < ./OrderDB.sql
Hoặc mở tệp OrderDB.sql
bằng MySQLWorkbench với tài khoản root
rồi chạy toàn bộ file này.
Tạo cấu trúc dự án
Chúng ta bắt đầu bằng cách đơn giản tạo một thư mục cho dự án của mình và một tệp có tên "main.go" bên trong đó. Sử dụng bằng lệnh sau:
mkdir crud-mysql
cd crud-to-mysql
touch main.go
Tạo cấu trúc dự án với các bước sau:
- Tạo module cho dự án:
go mod init crud
- Tạo gói (package) model (chứa các kiểu cấu trúc ánh xạ ORM) cho dự án và file Item.go:
mkdir model cd model touch Item.go
- Tạo gói (package) dal (Data Access Layer) cho dự án:
cd ../ mkdir dal cd dal
- Tạo tệp DbUtil.go chứa các hàm tiện ích kết nối với CSDL
touch DbUtil.go
- Tạo tệp ItemDal.go chưa các thao tác CRUD cho bảng Items trong CSDL OrderDB
touch ItemDal.go
Thực hiện mã lệnh cho dự án
Item.go
package model
type Item struct {
ItemId int64 `json:"itemId"`
ItemName string `json:"itemName"`
UnitPrice float64 `json:"unitPrice"`
Amount int32 `json:"amount"`
ItemStatus int16 `json:"status"`
ItemDescription string `json:"description"`
}
DbUtil.go
package dal
import (
"database/sql"
"fmt"
"time"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
//InitializeMySQL to OrderDB
func InitializeMySQL() {
dBConnection, err := sql.Open("mysql", "sinhnx:sinhnx.dev@tcp(127.0.0.1:3306)/OrderDB")
if err != nil {
fmt.Println("Connection Failed!!")
}
err = dBConnection.Ping()
if err != nil {
fmt.Println("Ping Failed!!")
}
db = dBConnection
dBConnection.SetMaxOpenConns(10)
dBConnection.SetMaxIdleConns(5)
dBConnection.SetConnMaxLifetime(time.Second * 10)
}
//GetConnection is get MySQL Connection
func GetConnection() *sql.DB {
if db == nil {
InitializeMySQL()
}
return db
}
//CloseStmt after run stmt
func CloseStmt(stmt *sql.Stmt) {
if stmt != nil {
stmt.Close()
}
}
//CloseRows when select
func CloseRows(rows *sql.Rows) {
if rows != nil {
rows.Close()
}
}
ItemDal.go
package dal
import (
"crud/model"
)
//InsertItem to OrderDB
func InsertItem(item model.Item) (int64, int64, error) {
GetConnection()
sqlQuery := "INSERT Items SET item_name=?, unit_price=?, amount=?, item_status=?"
stmt, err := db.Prepare(sqlQuery)
defer CloseStmt(stmt)
if err != nil {
return 0, 0, err
}
res, err := stmt.Exec(item.ItemName, item.UnitPrice, item.Amount, item.ItemStatus)
if err != nil {
return 0, 0, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return 0, 0, err
}
lastInsertId, err := res.LastInsertId()
return rowsAffected, lastInsertId, err
}
//UpdateItem in OrderDB
func UpdateItem(item model.Item) (int64, error) {
GetConnection()
sqlQuery := "UPDATE Items SET item_name=?, unit_price=?, amount=?, item_status=? WHERE item_id = ?"
stmt, err := db.Prepare(sqlQuery)
defer CloseStmt(stmt)
if err != nil {
return 0, err
}
res, err := stmt.Exec(item.ItemName, item.UnitPrice, item.Amount, item.ItemStatus, item.ItemId)
if err != nil {
return 0, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return 0, err
}
return rowsAffected, err
}
//DeleteItem in OrderDB
func DeleteItem(itemId int64) (int64, error) {
GetConnection()
sqlQuery := "DELETE FROM Items WHERE item_id = ?"
stmt, err := db.Prepare(sqlQuery)
defer CloseStmt(stmt)
if err != nil {
return 0, err
}
res, err := stmt.Exec(itemId)
if err != nil {
return 0, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return 0, err
}
return rowsAffected, err
}
//GetItem from itemId
func GetItem(itemId int64) (model.Item, error) {
sqlQuery := "SELECT item_id, item_name, unit_price, amount, item_status, item_description FROM Items WHERE item_id = ?"
stmt, err := db.Prepare(sqlQuery)
defer CloseStmt(stmt)
var item model.Item
if err != nil {
return item, err
}
res, err := stmt.Query(itemId)
defer CloseRows(res)
if err != nil {
return item, err
}
if res.Next() {
res.Scan(&item.ItemId, &item.ItemName, &item.UnitPrice, &item.Amount, &item.ItemStatus, &item.ItemDescription)
}
return item, err
}
main.go
package main
import (
"crud/dal"
"crud/model"
"fmt"
)
func main() {
item := model.Item{0, "Item 100", 15.5, 12, 1, ""}
rowsAffected, lastInsertedId, err := dal.InsertItem(item)
if err != nil {
fmt.Println("Insert error.")
} else {
if rowsAffected > 0 {
fmt.Println("Insert completed.")
item.ItemId = lastInsertedId
fmt.Printf("new item id is %d\n", item.ItemId)
}
}
//update item
item.ItemName = "Item 10001"
rowsUpdatedAffected, err := dal.UpdateItem(item)
if err != nil {
fmt.Println("Update error.")
} else {
if rowsUpdatedAffected > 0 {
fmt.Println("update completed.")
}
}
//get item
lastInsertedItem, err := dal.GetItem(lastInsertedId)
if err != nil {
fmt.Println("get error.")
} else {
fmt.Printf("%d - %s - %f - %d\n", lastInsertedItem.ItemId, lastInsertedItem.ItemName, lastInsertedItem.UnitPrice, item.Amount)
}
//delete item
rowsDeletedAffected, err := dal.DeleteItem(lastInsertedId)
if err != nil {
fmt.Println("delete error.")
} else {
if rowsDeletedAffected > 0 {
fmt.Println("delete completed.")
}
}
}
Biên dịch và chạy dự án
Gõ lệnh sau để biên dịch và chạy dự án
go build
./crud
Kết quả hiển thị:
Insert completed.
new item id is 20
update completed.
20 - Item 10001 - 15.500000 - 12
delete completed.
Mã nguồn tham khảo theo liên kết sau: https://github.com/sinhdev/go-lang-demo/tree/main/manipulate-with-database/crud-mysql
Nguồn tham khảo
https://golang.org/pkg/database/sql/
https://github.com/go-sql-driver/mysql
https://golangdocs.com/mysql-golang-crud-example
https://medium.com/@ranjeet.17may/golang-with-mysql-4f463489f340
https://tutorialedge.net/golang/golang-mysql-tutorial/
https://medium.com/@hugo.bjarred/mysql-and-golang-ea0d620574d2