Xóa dữ liệu trong MySQL từ Node.js

Một phần của tài liệu Giáo trình môn học phát triển mã nguồn mở với NodeJS (ngànhnghề thiết kế trang web) (Trang 57)

Để xóa dũ liệu trong CSDL MySQL từ một ứng dụng node.js bạn làm theo các bước sau.

B1: Thiết lập kết nối tới CSDL MySQL

B2: Thực hiện một câu lệnh DELETE bằng cách gọi phương thức query() trên

đối tượng connection.

B3: Ngắt kết nối từ máy chủ CSDL

Ví dụ xóa dữ liệu

Chương trình sau xóa một hàng trong bảng todos dựa trên id của hàng.

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 56 let mysql = require('mysql');

let config = require('./config.js');

let connection = mysql.createConnection(config); // Câu lệnh xóa

let sql = `DELETE FROM todos WHERE id = ?`; // Xóa hàng với id = 1

connection.query(sql, 1, (error, results, fields) => { if (error)

return console.error(error.message);

console.log('Deleted Row(s):', results.affectedRows); });

connection.end();

Trong ví dụ này, tôi sử dụng trình giữ chỗ (?) trong câu lệnh DELETE . Khi

chúng ta gọi phương thức query() trên đối tượng connection để thực hiện câu lệnh,

chúng ta đã chuyển dữ liệu tới câu lệnh DELETE làm đối số thứ hai. Trình giữ chỗ sẽ

được thay thế bằng giá trị đầu vào, do đó id sẽ lấy giá trị 1 khi truy vấn được thực

hiện.

DELETE FROM todos WHERE id = 1

Lưu ý rằng, nếu bạn có nhiều phần giữ chỗ, bạn cần truyền một mảng tới truy vấn để chuyển dữ liệu đến câu lệnh SQL.

Để lấy được số hàng được xóa, bạn có thể truy cập thuộc tính affectedRows của

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 57

Bài 4. Socket 1. Tổng quan về Socket.io

Socket.IO là một thư viện Javascript cho các ứng dụng web realtime (web thời

gian thực).

Nó cho phép giao tiếp hai chiều theo thời gian thực giữa các máy khách và máy

chủ web.

Nó có hai phần client-side library hoạt động trên trình duyệt, và server-side

library cho node.js.

Ứng dụng thời gian thực

Một ứng dụng thời gian thực (RealTime Application) là một ứng dụng hoạt động trong một khoản thời gian mà người dùng có thể cảm nhận được ngay lập tức thời.

Một số ví dụ về cá ứng dụng thời gian thực là.

Instant messengers– Các ứng dụng chat, trò chuyện như Whatsapp, Facebook Messenger, v.v. Bạn sẽ không cần phải làm mới ứng dụng/website

của mình để nhận được cácnội dung chat mới.

Push Notifications – Khi một ai đó tags bạn vào một bức ảnh trên Facebook, ban sẽ nhận được a thông báo ngay lập tức.

Collaboration Applications – Các ứng dụng như Google docs, cho phép

nhiều người cập nhật cùng một tài liệu cùng lúc và áp dụng thay đổi cho tất

cả các trường hợp của mọi người.

Game Online – Các trò chơi như Liên Minh Huyền Thoại, PUBG, Đột Kích, FIFA ONLINE 4 v.v , cũng là một số ví dụ về ứng dụng thời gian thực.

Tại sao nên chọn Socket.IO

 Socket.IO khá phổ biến, nó được sử dụng bới Microsoft

Office, Yammer, Zendesk, Trellovà nhiều tổ chức khác để xây dựng hệ thống thời gian thực mãnh mẽ.

 Nó là một trong những framework Javascript mãnh mẽ trên Github, và hầu

hết phụ thuộc vào module NPM.

 Socket.IO cũng có một cộng đồng lớn, có nghĩa là việc tìm kiếm sự giúp đỡ

rất dễ dàng.

2. Cài đặt Socket.IO

Trước khi cài đặt socket.IO bạn phải chắc chắn rằng thiết bị của mình đã cài đặt Node.js và NPM .

Để kiểm tra các bạn có thể chạy các lệnh sau node --version

npm --version

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 58 Tiếp theo các bạn hãy tạo ra cho mình một thư mục để lưu trữ các ví dụ của

mình. Ở đây tôi sẽ sử dụng thư mục socket.io-test và đồng thời cũng tạo ra

file package.json ở trong thư mục bằng lệnh. npm init

Bây giờ chúng ta cần phải cài đặt Express và Socket.IO.

Để cài đặt chúng hãy nhập lệnh sau vào command của bạn tại thư mục gốc của dự án.

npm install express socket.io

Ứng dụng Hello World

Tạo một tệp với tên app.js và đưa đoạn mã sau để thiết lập ứng dụng.

const express = require('express'); const app = express();

const server = require('http').Server(app); app.get('/', function(request, response){

response.sendFile(__dirname + '/index.html'); });

server.listen(8000, function(){

console.log(`Lắng nghe trên cổng 8000`); });

Tiếp theo, chúng ta tạo tệp index.html với nội dung sau.

<!DOCTYPE html> <html lang="en"> <head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial- scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Hello World</title>

</head> <body>

<h1>Hello World</h1> </body>

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 59 </html>

Để kiểm tra xem ứng dụng này có hoạt động hay không, các bạn vào command

tại thư mục gốc của project và chạy lệnh. Sau đó vào http://localhost:8000 để kiểm tra.

node app

Bây giờ tôi sẽ yêu cầu module Socket.IO và mỗi khi có người kết nối tới ứng dụng sẽ hiện thị “Người dùng đã kết nối tới ứng dụng” và “Người dùng ngắt kết nối” mỗi khi có người dùng đóng ứng ụng.

File app.js

const express = require('express'); const app = express();

const server = require('http').Server(app); const io = require('socket.io')(server) app.get('/', function(request, response){

response.sendFile(__dirname + '/index.html'); });

io.on('connection', function(socket){

console.log('Người dùng đã kết nối tới ứng dụng') socket.on('disconnect', function(){

console.log('Người dùng đã ngắt kết nối tới ứng dụng'); })

});

server.listen(8000, function(){

console.log(`Lắng nghe trên cổng 8000`); });

require('socket.io')(server) tạo ra một cá thể socket.io gắn với máy chủ http.

Trình xử lý sự kiện io.on xử lý kết nối (connection), ngắt kết nối (disconnection) v.v.

Các sự kiện trong đó sử dụng đối tương socket.

Ở trên tôi đã thiết lập máy chủ để ghi nhật ký các thông báo khi người dùng kết nối tới ứng dụng, và khi người dùng rời khỏi ứng dụng.

Bây giờ chúng ta phải yêu cầu script ở phía máy khách và khởi tạo đối tượng socket ở đó, để các máy khách có thể thiết lập các kết nối khi được yêu cầu.

Tập tin được sử dụng bới máy chủ socket.io là „/socket.io/socket.io.js„

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 60 <!DOCTYPE html>

<html lang="en"> <head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial- scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Hello World</title> </head> <body> <h1>Hello World</h1> </body> <script src="/socket.io/socket.io.js"></script> <script>

var socket = io(); </script>

</html>

Nếu bạn chạy ứng dụng và truy cập localhost:3000 bạn sẽ nhận được thông báo

“Hello Word” trên trình duyệt.

Để kiểm tra nhật ký ở bảng điều khiển console các bạn sẽ nhận được các thông

báo sau.

3. Xử lý sự kiện trong Socket.IO

3.1 Tổng quan module Events trong Node.js

“Module events với lớp đối tượng EventEmitter bên trong nó chính là cốt lõi của

kiến trúc hướng sự kiện không đồng bộ trong Node.js, hầu hết các core module built-in

trong Node.js đều kế thừa từ module events này.” Vậy chính xác thì module này dùng để làm gì?

Câu trả lời đơn giản là:“Nó cho phép bạn lắng nghe các sự kiện và gán các hành động để chạy khi những sự kiện đó xảy ra.”

Nếu bạn đã từng làm việc với Javascript phía trình duyệt, bạn chắc sẽ từng biết về các sự kiện chuột hay bàn phímkhi người dùng phía client tương tác với ứng dụng

nhưonclick, onkeyup…vv, dựa vào những sự kiện đó mà chúng ta sẽ viết code xử lý

hành động tiếp theo.

Eventscũng giống như vậy, ngoại trừ việc đó là chúng ta có thể tự định nghĩa sự

kiện, phát ra sự kiện khi chúng ta muốn, không cần thiết phải dựa trên tương tác của người dùng.

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 61

“Module Events trong Node.js hỗ trợ cho chúng ta lập trình, viết code theo kiến trúc Event-Driven.”

“Events là một trong những lý do làm cho Node.js được nói là có tốc độ cao:Vì hầu hết code corecủaNode.jsđều dựa trên mô hìnhEvent-Driven này nên

thay vì đọc tất cả những file cần thiết với mọi request (ví dụ như PHP). Thì thằng Node này lại chỉ khởi động server, khởi tạo hết các biến, khai báo các function mà

mình viết rồi cứ thế ngồi đợi một sự kiện nào đó xảy ra và thực thi chức năng.

“Khi sử dụng Events thì việc ghép nối các đoạn code của chúng ta lại sẽ khá lỏng lẻo”:Nghĩa là khi một sự kiện được phát ra, nhưng nếu không có đoạn code nào lắng nghe sự kiện đó, thì cũng không sao hết, nó sẽ chẳng làm gì luôn. Như vậy khi cầnxóa code, cụ thể là xóa một “bên lắng nghe”hoặc một “sự kiện không cần

dùng đến nữa”thì cũng không bao giờ bị thông báo lỗi code Javascript gì cả.

Sử dụng Events để thay thế cho Callbacks trong những trường hợp cụ

thể”(không phải thay thế hoàn toàn): Node.js có rất nhiều phương thức chạy không

đồng bộ (asynchronous), đồng nghĩa với việc có rất nhiều tác vụ liên quan đến nhau, tác vụ sau cần dữ liệu của tác vụ trước để chạy, nếu dùngcallbackthì code của bạn sẽ ngày càng trông giống một cái phễu lớn, người ta gọi đó làCallback Hell.

Để ngăn chặn Callback Hell, nhiều class trong node.js đã sử dụng events để phát ra sự kiện, lắng nghe sự kiện và thực hiện các hành động ứng với các sự kiện. Như vậy sẽ tổ chức code theo một cấu trúc khác gọn gàng hơn, không gặp phải “callback heo”nữa.

3.2 Sử dụng module Events.

Sau khi đã phân tích khá nhiều lý thuyết ở trên, bây giờ chúng ta sẽ đi vào cách sử dụng module.

Mình sẽ viết ví dụ đơn giản đầu tiên, Viết code để xử lý bài toán: Khi con mèo chạy, cái chuông trên cổ con mèo sẽ kêu ring ring.

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 62

* Created by trungquandev.com's author on 30/09/2018. */

const events = require("events");

let EventEmitter = new events.EventEmitter(); let ringBell = () => {

console.log("ring ring ring..."); }

// Lắng nghe sự kiện khi mèo chạy thì gọi tới function ringBell

EventEmitter.on("catRun", ringBell);

// Phát sự kiện con mèo chạy.

EventEmitter.emit("catRun");

Đầu tiên lànạp moduleevents, đối tượngeventsnày có một thuộc tính duy nhất đó là lớpEventEmitter.

Bên trong EventEmitter có 2 phương thức chính làemiton tương ứng vớiphátlắng nghesự kiện.

Khi chạyEventEmitter.emitsẽemit (phát ra) một sự kiện tên là“catRun” do

chúng ta đặt, và rồiEventEmitter.onsẽ lắng nghe sự kiện“catRun”sau đó chạy

function ringBell. Nếu bỏ đi một trong 2 method.emit hay .onở trên thì chương trình cũng không bị lỗi gì cả.

Ngoài ra chúng ta còn có thểinclude thêm dữ liệukhi emit sự kiệnnhư thế

này:

EventEmitter.emit("catRun", data);

Thì ở bên lắng nghe:

EventEmitter.on("catRun", (data) => { // Làm gì đó với data nhận được ở đây...

});

Chúng ta có thể lắng nghe nhiều lần trên cùng một sự kiện như thế này:

EventEmitter.on("catRun", (data) => { // Sử dụng data cho công việc 1.

});

EventEmitter.on("catRun", (data) => { // Sử dụng data cho công việc 2.

});

EventEmitter.on("catRun", (data) => { // Sử dụng data cho công việc 3.

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 63

Mặc định Node.js cho phép 10 listeners trên cùng một sự kiện, có nghĩa là trong sự kiện“catRun”ở trên, Tới công việc thứ 11 Node.js sẽ thông báo lỗi. Nhưng không sao cả, chúng ta có thể sử dụng hàmsetMaxListeners để tăng giới hạn đó.

EventEmitter.setMaxListeners(17); // ví dụ mình nâng lên 17 listeners.

Còn rất nhiều phương thức hay nữa như:

.once();.removeListener();.removeAllListener();.listener();…vv.

3.3 Viết một module khác kế thừa module Events

Trong thực tế khi viết code, sẽ còn hay hơn nữa khi mà chúng ta có thể viết một

Class kháckế thừacác phương thức cũng như thuộc tính của lớp

EventEmitter trong module events. Vì EventEmittercũng là Javascript thông

thường và có thể sử dụng trong các module khác.

Nếu từng sử dụng module http của node.js,bạn có thể thấy nó cũng có một phương thức là.on();

/**

* Created by trungquandev.com's author on 30/09/2018. */

var http = require("http"); var server = http.createServer();

server.on("request", function (req, res) { res.end("This is the response.");

});

server.listen(8017);

Ví dụ ở trên cho thấy phương thức.on();của lớpEventEmitterđã trở thành một phần của lớphttp.createServer();

Khi server nhận được một request từ trình duyệt, nó sẽ emitmột sự kiện có tên

“request”, sau đó mộtlistener chính là server.on(); lắng nghe và hành động. Cụ thể hành động ở đây là trả về một chuỗi text:“This is the response.”

–Bây giờ, bắt đầu ví dụ chính của chúng ta:

“Mình sẽ viết một module UserModel.js kế thừa module events, sau đó viết một

file index.js sử dụng chính module UserModel này mỗi khi lưu một user mới vào database thì sẽ emit một sự kiện thông báo là đã lưu trữ user thành công.”

UserModel.js

const EventEmitter = require("events").EventEmitter; // Fake database.

let database = { users: [

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 64

{id: 2, name: "Trungquandev02", occupation: "writer"}, {id: 3, name: "Trungquandev03", occupation: "designer"} ]

};

class UserModel extends EventEmitter { constructor() {

super(); // Từ khóa super được sử dụng để gọi các hàm trên đối tượng cha, ở đây đối tượng cha là EventEmitter

}

// Lưu user vào "database fake" ở trên.

saveUser(user) {

database.users.push(user);

this.emit("saved", user); // sử dụng hàm .emit của thằng EventEmitter

}

// Liệt kê toàn bộ user hiện tại.

allUser() { return database.users; } } module.exports = UserModel; index.js

const UserModel = require("./UserModel"); let User = new UserModel();

// Vì đã kế thừa events nên class User có thể sử dụng method .on()

User.on("saved", (user) => {

console.log(`New user saved: ${user.name} - ${user.occupation}`); });

// Lưu thêm 2 thằng user mới.

let trungquandev04 = {id: 4, name: "Trungquandev04", occupation: "Code xịn (─‿‿─)"};

let trungquandev05 = {id: 5, name: "Trungquandev05", occupation: "Code lởm

(-.-)"};

User.saveUser(trungquandev04); User.saveUser(trungquandev05);

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 65

let allUser = User.allUser(); console.log(allUser);

Kết quả sau khi chạy:

Như vậy, có thể thấy, module UserModel của chúng ta sau khi kế

thừa EventEmitter, đã có thểtự pháttự lắng nghe các sự kiện. Cool huh? =)) 😀

3.4 Phân biệt events với socket.io

Chắc có khá nhiều bạn khi mới làm quen với node.jsthì cũng từng nghe qua cái

tên khá phổ biến đó làsocket.io để làm các ứng dụngreal-time. Khi mới tìm hiểu Node.js mình từng cảm thấy chút mâu thuẫn giữa 2 thành phầnevents và socket.io này.

Cả 2 module trên đều có chung một điểm là emitphát sự kiện rồionđể lắng nghe sự kiện vàgửi – nhậncác tham số dữ liệu từ chúng.

Điểm khác quan trọng giữa 2 thành phầnnày đó là:

Socket.iochỉ cho phép phát và lắng nghesự kiệnqua lạigiữa client và server.

Eventschỉ cho phépphát và lắng nghesự kiệntrong nội bộ server.

Còn nếu muốn sử dụng socket.iophát và nhận sự kiện ngay trên server luônthì có một gói module khác làsocket.io-client.

4. Socket.IO Broadcasting

Broadcasting nghĩa là gửi một tin nhắn đến tất cả người dùng đang kết nối. Broadcasting có thể thực hiện ở nhiều cấp độ. Chúng ta có thể gửi tin nhắn đến tất cả người dùng đang kết nối, khách hàng có tên bất kỳ và cả khách hàng ở trong một phòng cụ thể. Để phát một sự kiện cho tất cả các khách hàng, chúng ta có thể sử dụng

phương thức io.sockets.emit

Lưu ý: Thao tác này sẽ phát ra sự kiện cho TẤT CẢ máy khách đang được kết nối.

Trong ví dụ này tôi sẽ phát ra sự kiện cho tất cả máy khách đang kết nối. Thay

đổi nội dung file app.js như sau.

const express = require('express'); const app = express();

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 66 const io = require('socket.io')(server)

app.get('/', function(request, response){

response.sendFile(__dirname + '/index.html'); });

var clients = 0;

io.on('connection', function(socket){ clients++;

io.sockets.emit('broadcast', {description: `${clients} người dùng đã kết nối`})

socket.on('disconnect', function(){ clients--;

io.sockets.emit('broadcast', {description: `${clients} người dùng đã kết nối`})

}) });

server.listen(8000, function(){

console.log(`Lắng nghe trên cổng 8000`);

});

Về phía máy khách, chúng ta tiến hành xử lý sự kiện broadcast. File index.html

<!DOCTYPE html> <html lang="en"> <head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial- scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Hello World</title> </head> <body> <h1>Hello World</h1> </body> <script src="/socket.io/socket.io.js"></script> <script>

Phạm Đình Nam –Trường Caođẳng nghề Đà Lạt Trang 67

Một phần của tài liệu Giáo trình môn học phát triển mã nguồn mở với NodeJS (ngànhnghề thiết kế trang web) (Trang 57)