[SQLITE] Dùng NodeJS thêm sửa xóa file SQLite (ok)
https://viblo.asia/p/dung-nodejs-them-sua-xoa-file-sqlite-bWrZn1wmKxw
https://github.com/mapbox/node-sqlite3
Ví dụ đã hoàn thành :)
C:\Users\Administrator\Desktop\sqlite\package.json
{
"name": "sqlite",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bluebird": "^3.7.2",
"sqlite3": "^5.0.0"
}
}
C:\Users\Administrator\Desktop\sqlite\main.js
C:\Users\Administrator\Desktop\sqlite\dao.js
C:\Users\Administrator\Desktop\sqlite\project_repository.js
C:\Users\Administrator\Desktop\sqlite\task_repository.js
Dùng NodeJS thêm sửa xóa file SQLite
This post has been more than 2 years since it was last updated.

Trong bài này, mình sẽ trình bày cách sử dụng Node.js kết hợp với SQLite 3 để thêm sửa xóa các bản ghi Database dạng CSDL quan hệ (có Table, Row, Column đàng hoàng). Trước giờ NodeJS thường được dùng với No-SQL ví dụ MongoDB, JSON. Bài này sẽ sử dụng SQLite 3.
Nói thêm một chút, SQLite là một cơ sở dữ liệu quan hệ nhưng không cần server mà nó lưu trữ thành dạng file bê đi đâu cũng được ví dụ như một file word, exel vậy, rất là tiện lợi nếu cần đem phần mềm và cơ sở dữ liệu copy vào đâu cũng chạy.
Cài đặt môi trường
Mình sẽ bắt đầu bằng cách gõ lệnh npm init bên trong một thư mục mới tạo có tên là node-sqlite-tutorial. Đây là lệnh để tạo mới một project bằng NodeJS. Khi chạy lệnh này thì Node sẽ hỏi chúng ta các câu hỏi cần thiết để tạo project. Ví dụ tên project, phiên bản, tác giả... Điền xong các bạn sẽ được như hình:
Tiếp theo, mình sẽ cần cài đặt gói sqlite3 qua npm như sau (trỏ cmd đến thư mục hiện tại và gõ như bên dưới):
Ngoài sqlite3 mình sẽ cài đặt Bluebird để mình có thể sử dụng chức năng Promises quen thuộc trong lập trình Javascript (giúp thao tác với dữ liệu).
Bây giờ mình sẽ tạo một file trống ngay bên cạnh tệp package.json gọi là database.sqlite3 nơi SQLite sẽ lưu trữ dữ liệu trong đó.
Thiết kế CSDL
Để lưu trữ dữ liệu cho bài toán mình sẽ thiết kế một mẫu dữ liệu quan hệ gồm 2 bảng nối nhau, kiểu master-detail.
Giả sử mình cần tạo một ứng dụng dùng để quản lý dự án. Mỗi dự án có thể có một hoặc nhiều task cần hoàn thành, cần biết rõ task hoàn thành hay chưa. Mình có thể demo dữ liệu trong bảng như sau:
Bảng projects
id
name
1
Write Node.js - SQLite Tutorial
2
Testing Functionalities
Bảng tasks
id
name
description
isCompleted
projectId
1
Outline
High level overview of sections
1
1
2
Write
Write article contents and code examples
0
1
Ok, bây giờ mình biết dữ liệu gồm những gì, giờ hãy đi tạo bảng SQL để chứa được dữ liệu của 2 bảng trên
Tạo ra file Cơ sở dữ liệu
Để bắt đầu, mình sẽ cần tạo một file main.js cùng với file dao.js (Toàn bộ hàm thêm sửa xóa sẽ viết chung trong đây cho gọn) trong cùng thư mục với file package.json (thư mục gốc của project).
Bên trong dao.js mình sẽ thêm một hàm khởi tạo để kết nối đến một file sqlite3 có sẵn sử dụng Bluebird . Hàm khởi tạo này sẽ được gán vào một biến dùng chung cố định là this.db. Hàm khởi tạo này cũng sẽ được đưa vào class AppDAO để export nó ra bên ngoài (cho phép các class khác ở file khác có thể nhìn thấy và gọi hàm khởi tạo class, từ khóa export trong js tương đương từ khóa public trong lập trình hướng đối tượng).
Việc kết nối đến cơ sở dữ liệu đã được mô tả bằng các comment bên trên. Cơ bản thì bạn khởi tạo một class AppDAO và đưa đường dẫn đến tệp cơ sở dữ liệu SQLite mà bạn muốn kết nối, bạn sẽ được một biến this.db để bắt đầu thao tác với CSDL. Biến this.db này đã kế thừa đầy đủ các hàm viết sẵn của Node.js sqlite3 giúp thực thi các truy vấn (query) đến file dbFilePath. Trong ví dụ này chúng ta sẽ dùng đến 3 hàm sau đây:
run: Được sử dụng để tạo hoặc thay đổi bảng và chèn hoặc cập nhật dữ liệu bảng.
get: Chọn một hàng dữ liệu từ một hoặc nhiều bảng.
all: Chọn nhiều hàng dữ liệu từ một hoặc nhiều bảng.
Để bắt đầu, hãy khám phá hàm run. Cú pháp của nó như sau:
Tham số đầu tiên được truyền cho run (...) là một chuỗi SQL được thực thi và là tham số bắt buộc. Tham số thứ hai là một mảng tham số tùy chọn mà thư viện sqlite3 sẽ hoán đổi cho bất kỳ ký tự '?' trong tham số truyền vào. Tham số thứ 3 là một hàm callback để bắn ra lỗi nếu có lỗi sau khi thực thi.
Để áp dụng vào class AppDAO của chúng ta mình sẻ dùng đến Promise của Javascript để đặt một lệnh run query và đợi kết quả trả về. Hàm được viết thêm vào file AppDAO như sau:
Như vậy là từ bây giờ chúng ta có thể gọi hàm AppDAO.runquery(...) và truyền vào 2 tham số cho nó để nó chạy kết nối đến db và lấy ra dữ liệu cần thiết cho mình, tùy thuộc vào câu sql truyền vào.
Chúng ta có 2 bảng là projects và tasks. Để làm tinh gọn code và phân tách rõ ràng, mình sẽ viết riêng ra 2 class để thao tác dữ liệu với 2 bảng độc lập.
Giờ, mình thêm hai file nữa vào dự án của mình là project_repository.js và task_repository.js. Bên trong project_repository.js mình định nghĩa một class được gọi là ProjectRepository. Nó có một hàm khởi tạo đầu vào là một đối tượng AppDAO và một hàm createTable thực thi một query SQL. Chúng ta hãy xem qua code như sau
Tương tự như vậy chúng ta tạo file task_repository.js với cấu trúc như bên dưới. Trong hàm createTable sẽ chứa câu lệnh tạo bảng tasks
Như vậy là query SQL để tạo bảng đã hoàn tất, tiếp đến mình sẽ chuyển sang các hàm chèn dữ liệu vào các bảng.
Chèn dữ liệu
Trong class ProjectRepository, mình cần thêm một hàm create nhận tên của dự án để tạo và thực thi câu lệnh INSERT thích hợp bằng AppDAO.runquery(...). Lưu ý cách mình đã sử dụng '?' để đại diện cho giá trị cho tên của dự án và sau đó đặt tham số name trong tham số mảng params tùy chọn vào hàm runquery(...). Đây là viết theo kiểu câu lệnh truy vấn được tham số hóa, nó sẽ nhận sql đầu vào để giảm thiểu rủi ro bị tấn công bằng SQL injection.
Một hàm khởi tạo tương tự cho class TaskRepository.
Bây giờ chúng ta đã có thể INSERT dữ liệu vào cơ sở dữ liệu. Giờ hãy chuyển qua chức năng để cập nhật CSDL.
Cập nhật dữ liệu
Trong class ProjectRepository, mình sẽ thêm một hàm update tất cả các trường cho bản ghi cơ sở dữ liệu của project. Đầu vào cần phải biết là project nào cần được update. Sử dụng hàm AppDAO.runquery(...), như sau:
Tiếp theo là thêm hàm cập nhật tương ứng vào class TaskRepository.
Xóa dữ liệu
Chức năng cuối cùng cần thực hiện là xóa các bản ghi trong cơ sở dữ liệu. Đối với chức năng này mình sẽ một lần nữa sử dụng AppDAO.runquery(...) kết hợp với các hàm delete cho cả hai class ProjectRepository và TaskRepository.
Đối với ProjectRepository viết thêm vào như sau:
Và cho TaskRepository viết như thế này:
Đã xong, chúng ta đã viết xong toàn bộ các hàm THÊM, SỬA, XÓA cho cở sở dữ liệu của 2 bảng projects và tasks. Tiếp theo, mình sẽ giới thiệu hai hàm Node.js sqlite3 có liên quan đến get và all.
Đọc dữ liệu
Để đọc dữ liệu ra từ CSDL sau khi đã được thêm vào, hàm get được sử dụng để truy xuất một dòng dữ liệu, còn hàm all được sử dụng để truy vấn nhiều dòng dữ liệu đồng thời.
Cú pháp để get như sau:
Ở đây db là một đối tượng kết nối đến file sqlite3. Bạn sẽ thấy rằng cú pháp về cơ bản giống với hàm run, nhưng ở hàm callback sau khi thực thi xong query SELECT sẽ có thêm một tham số result. Tham số này là bắt buộc vì nó sẽ chứa object (dòng dữ liệu trong bảng) đã được lấy ra và vứt vào đây.
Cú pháp của hàm all về cơ bản là giống get tham số thứ hai cho hàm callback là một mảng các kết quả được truy vấn trả về, như sau:
Cũng giống như mình đã làm với hàm run sqlite3 bên trên, mình sẽ thực hiện các hàm get và all sử dụng bluebird Promise trong class AppDAO như hình dưới đây:
Bây giờ mình có thể sử dụng các hàm này trong các lớp ProjectRepository và TaskRepository để lấy dữ liệu từ cơ sở dữ liệu SQLite.
Để bắt đầu, mình sẽ thêm hàm getById cho mỗi lớp để chọn bản ghi theo id.
Trong ProjectRepository mình viết thêm:
Để chứng minh AppDAO.all(...), mình sẽ thêm khả năng chọn tất cả các dự án cũng như tất cả các nhiệm vụ cho một dự án cụ thể.
Mã để SELECT tất cả các dự án trông như thế này:
Sau đó, để chọn tất cả các nhiệm vụ cho một dự án, mình sẽ sử dụng một hàm được gọi là getTasks(projectId)dự kiến id của dự án bạn muốn các nhiệm vụ.
Đặt Mã truy cập dữ liệu để sử dụng Cho đến nay mình đã cơ bản tạo ra một thư viện truy cập dữ liệu cho dự án hư cấu này và ứng dụng theo dõi nhiệm vụ. Những gì mình muốn làm bây giờ là sử dụng nó để tải lên dữ liệu thử nghiệm của mình được hiển thị trong các bảng trong phần Thiết kế cơ sở dữ liệu .
Trong tập tin main.js mình sẽ muốn kéo trong AppDAO, ProjectRepository và class TaskRepository qua require. Sau đó, mình sẽ sử dụng chúng để tạo ra các bảng, điền chúng với dữ liệu sau đó, lấy dữ liệu từ cơ sở dữ liệu và hiển thị tới bàn điều khiển.
Biên dịch và chạy hàm main bằng lệnh Node như sau:
Và bạn sẽ thấy kết quả như hình dưới đây. Tất cả các hàm đều đã chạy ngon.
Kết luận
Trong hướng dẫn này, mình đã xem lại các khái niệm cơ bản về các hàm API sqlite3 của Node.js và đã trình bày cách bạn có thể dùng nó trong lập trình hướng đối tượng JavaScript . Và viết code theo kiểu không đồng bộ (async) dựa trên Promise để chương trình chạy nhanh hơn gọn hơn.
Như mọi khi, mình cảm ơn bạn đã đọc!
Bài này là một bài dịch, link bài gốc ở đây: http://stackabuse.com/a-sqlite-tutorial-with-node-js/
Last updated
Was this helpful?