MySQL
Mysql là cơ sở dữ liệu quan hệ mã nguồn mở phổ biến nhất hiện nay. Các kiến thức sql cụ thể sẽ không được trình bày quá nhiều ở đây, nếu bạn chưa biết vui lòng tự học trước. Bài viết này chỉ đơn giản giải thích cách sử dụng Go để thao tác sql. Trong dự án thực tế, thông thường không sử dụng trực tiếp trình điều khiển để thao tác cơ sở dữ liệu mà sử dụng các framework ORM. Ở đây sử dụng thư viện sqlx, là một thư viện mở rộng của thư viện sql tiêu chuẩn, không có nhiều chức năng như ORM nhưng bù lại rất đơn giản và gọn nhẹ. Nếu bạn muốn sử dụng ORM, có thể tìm hiểu các thư viện như Gorm, Xorm, Ent.
Phụ thuộc
Tải xuống thư viện sqlx
$ go get github.com/jmoiron/sqlxsqlx hoặc thư viện database/sql tiêu chuẩn hỗ trợ không chỉ MySQL, bất kỳ loại nào thực hiện giao diện driver.Driver đều được hỗ trợ, ví dụ:
- PostgreSQL
- Oracle
- MariaDB
- SQLite
- Và các cơ sở dữ liệu quan hệ khác
Để sử dụng cơ sở dữ liệu tương ứng, cần thực hiện trình điều khiển cơ sở dữ liệu. Trình điều khiển có thể do bạn tự viết hoặc từ thư viện bên thứ ba. Trước khi sử dụng, bạn cần đăng ký trình điều khiển bằng sql.Register, sau đó mới có thể sử dụng. Tuy nhiên, các thư viện trình điều khiển tải xuống thường tự động đăng ký trình điều khiển, không cần bạn phải đăng ký thủ công.
func Register(name string, driver driver.Driver)Vì MySQL khá phổ biến và cũng đơn giản nhất, nên bài viết này sử dụng MySQL để giải thích. Các cơ sở dữ liệu quan hệ khác hoạt động tương tự, tải xuống thư viện trình điều khiển MySQL
$ go get github.com/go-sql-driver/mysqlKết nối với cơ sở dữ liệu
Thông qua hàm sqlx.Open, có thể mở một kết nối cơ sở dữ liệu. Nó nhận hai tham số, tham số đầu tiên là tên trình điều khiển, tham số thứ hai là nguồn dữ liệu (thường gọi là DSN).
func Open(driverName, dataSourceName string) (*DB, error)Tên trình điều khiển là tên được sử dụng khi đăng ký trình điều khiển, cần giữ nhất quán. DSN là địa chỉ kết nối của cơ sở dữ liệu, mỗi loại cơ sở dữ liệu có thể khác nhau. Đối với MySQL, nó như sau
db,err := sqlx.Open("mysql","root:123456@tcp(127.0.0.1:3306)/test")Chuẩn bị dữ liệu
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`age` tinyint(0) NULL DEFAULT NULL,
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('12132', '张三', 35, '北京市');
INSERT INTO `user` VALUES ('16162', '王五', 22, '上海市');
SET FOREIGN_KEY_CHECKS = 1;Truy vấn
Truy vấn và ánh xạ kết quả vào cấu trúc
var db *sqlx.DB
type Person struct {
UserId string `db:"id"`
Username string `db:"name"`
Age int `db:"age"`
Address string `db:"address"`
}
func init() {
conn, err := sqlx.Open("mysql", "root:wyh246859@tcp(127.0.0.1:3306)/test")
if err != nil {
fmt.Println("Open mysql failed", err)
return
}
db = conn
}
func main() {
query()
defer db.Close()
}
func query() {
var person Person
// Một là Get, nhiều là Select
err := db.Get(&person, "select * from user where id = ?", "12132")
if err != nil {
fmt.Println("query failed:", err)
return
}
fmt.Printf("query succ:%+v", person)
}
func list() {
var perons []Person
err := db.Select(&perons, "select * from user")
if err != nil {
fmt.Println("list err", err)
return
}
fmt.Printf("list succ,%+v", perons)
}Thêm mới
Thêm dữ liệu mới
func insert() {
result, err := db.Exec("insert into user value (?,?,?,?)", "120230", "李四", 12, "广州市")
if err != nil {
fmt.Println("insert err:", err)
return
}
id, err := result.LastInsertId()
if err != nil {
fmt.Println("insert err:", err)
return
}
fmt.Println("insert succ:", id)
}Cập nhật
Cập nhật dữ liệu
func update() {
res, err := db.Exec("update user set name = ? where id = ?", "赵六", "120230")
if err != nil {
fmt.Println("update err:", err)
return
}
eff, err := res.RowsAffected()
if err != nil || eff == 0 {
fmt.Println("update err:", err)
return
}
fmt.Println("Update succ")
}Xóa
Xóa dữ liệu
func delete() {
res, err := db.Exec("delete from user where id = ?", "120230")
if err != nil {
fmt.Println("delete err:", err)
return
}
eff, err := res.RowsAffected()
if err != nil || eff == 0 {
fmt.Println("delete err:", err)
return
}
fmt.Println("delete succ")
}Giao dịch
func (db *DB) Begin() (*Tx, error) // Bắt đầu một giao dịch
func (tx *Tx) Commit() error // Cam kết một giao dịch
func (tx *Tx) Rollback() error // Lùi lại một giao dịchKhi bắt đầu một giao dịch, để an toàn thường thêm defer tx.Rollback(). Nếu quá trình xảy ra lỗi, sẽ lùi lại. Nếu giao dịch được cam kết thành công, việc lùi lại này đương nhiên là vô hiệu.
func main() {
transation, err := db.Begin()
if err != nil {
fmt.Println("transation err")
}
defer transation.Rollback()
insert()
query()
update()
query()
delete()
transation.Commit()
}