Data persistence in web applications with Node.js
Seoul National University of Science and Technology
Information Technology Management
Lecture slides index
May 20, 2025
| origin | destination | duration |
|---|---|---|
| New York | London | 415 |
| Shanghai | Paris | 760 |
| Istanbul | Tokyo | 700 |
| New York | Paris | 435 |
| Moscow | Paris | 245 |
| Lima | New York | 455 |
Popular DBMSs
Types of databases:

CREATE TABLE flights (
id INTEGER PRIMARY KEY AUTOINCREMENT,
origin TEXT NOT NULL,
destination TEXT NOT NULL,
duration INTEGER NOT NULL
);SELECT statement is used to return data from a database.



WHERE clause filters out rows based on their columns’ data values.WHERE portion of a SELECT statement can use the following operators:










IN operator allows you to specify multiple values in a WHERE clause.IN operator is a shorthand for multiple OR condition

LIKE operator is used for performing pattern-based searches in a database.%represents zero, one, or multiple characters_ represents one, single character

UPDATE and SET keywords.DELETE keyword:Warning
| id | origin | destination | duration |
|---|---|---|---|
| 1 | New York | London | 415 |
| 2 | Shanghai | Paris | 760 |
| 3 | Istanbul | Tokyo | 700 |
| 4 | New York | Paris | 435 |
| 5 | Moscow | Paris | 245 |
| 6 | Lima | New York | 455 |
| id | origin | origin_code | destination | destination_code | duration |
|---|---|---|---|---|---|
| 1 | New York | JFK | London | LHR | 415 |
| 2 | Shanghai | PVG | Paris | CDG | 760 |
| 3 | Istanbul | IST | Tokyo | NRT | 700 |
| 4 | New York | JFK | Paris | CDG | 435 |
| 5 | Moscow | SVO | Paris | CDG | 245 |
| 6 | Lima | LIM | New York | JFK | 455 |
| id | code | city |
|---|---|---|
| 1 | JFK | New York |
| 2 | PVG | Shanghai |
| 3 | IST | Istanbul |
| 4 | LHR | London |
| 5 | SVO | Moscow |
| 6 | LIM | Lima |
| 7 | CDG | Paris |
| 8 | NRT | Tokyo |
| id | origin | destination | duration |
|---|---|---|---|
| 1 | New York | London | 415 |
| 2 | Shanghai | Paris | 760 |
| 3 | Istanbul | Tokyo | 700 |
| 4 | New York | Paris | 435 |
| 5 | Moscow | Paris | 245 |
| 6 | Lima | New York | 455 |
| id | origin_id | destination_id | duration |
|---|---|---|---|
| 1 | 1 | 4 | 415 |
| 2 | 2 | 7 | 760 |
| 3 | 3 | 8 | 700 |
| 4 | 1 | 7 | 435 |
| 5 | 5 | 7 | 245 |
| 6 | 6 | 1 | 455 |
| id | first | last | flight_id |
|---|---|---|---|
| 1 | Harry | Potter | 1 |
| 2 | Ron | Weasley | 1 |
| 3 | Hermione | Granger | 2 |
| 4 | Draco | Malfoy | 4 |
| 5 | Luna | Lovegood | 6 |
| 6 | Ginny | Weasley | 6 |
| id | first | last |
|---|---|---|
| 1 | Harry | Potter |
| 2 | Ron | Weasley |
| 3 | Hermione | Granger |
| 4 | Draco | Malfoy |
| 5 | Luna | Lovegood |
| 6 | Ginny | Weasley |
| person_id | flight_id |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 2 | 4 |
| 3 | 2 |
| 4 | 4 |
| 5 | 6 |
| 6 | 6 |
WHERE constraint or the JOIN keyword.Multi table WHERE syntax
SELECT people.first, flights.origin, flights.destination
FROM people, flights, passengers
WHERE people.id = passengers.person_id
AND flights.id = passengers.flight_id;SELECT people.first, flights.origin, flights.destination
FROM passengers
JOIN people ON passengers.person_id = people.id
JOIN flights ON passengers.flight_id = flights.id;| first | origin | destination |
|---|---|---|
| Harry | New York | London |
| Ron | New York | London |
| Hermione | Shanghai | Paris |
| Draco | New York | Paris |
| Luna | Lima | New York |
| Ginny | Lima | New York |



sqlite vs sqlite3sqlite3 is the official SQLite bindings for Node.js.sqlite3 is the most popular module used to connect to a SQLite database in Node.jsfs module, sqlite3 functions by default use callbacks for results and errorssqlite which is a promise-based wrapper built on top of sqlite3.
sqlite3 and sqlite modules in your project.const sqlite3 = require('sqlite3');
const sqlite = require('sqlite');
const fs = require('fs');
const DB_NAME = "airline.db";
/**
* Establishes a database connection to the database and returns the database object.
* Any errors that occur should be caught in the function that calls this one.
* @returns {Promise<sqlite3.Database>} - The database object for the connection.
*/
async function getDBConnection(dbFileName) {
const db = await sqlite.open({
filename: dbFileName,
driver: sqlite3.Database
});
console.log("Connection succesful.")
return db;
}getDBConnection function, you will see a file called airline.db created in your root folder..all()
.exec()
.get()
.run()
getDbConnection function
async function.then/.catch syntaxflights_schema.sql file hereasync function loadDB(dbFileName, sqlFileName) {
try {
let db = await getDBConnection(dbFileName);
const sql = fs.readFileSync(sqlFileName, 'utf8');
const result = await db.exec(sql);
console.log('Database loaded successfully.');
console.log(result);
await db.close();
} catch (err) {
console.error('Failed to load database:', err.message);
}
}
loadDB(DB_NAME, "flights_schema.sql");db.close()close function closes the db connection and ensures that its associated resources are deallocated..close() returns a Promise, so it must be awaiteddb object, you can now execute SQL queries with db.alldb.exec(sqlString)Promise which resolves to undefined (nothing is returned by this method)async function executeInsert() {
try {
let db = await getDBConnection(DB_NAME);
const sql = "INSERT INTO flights (origin, destination, duration) VALUES (\"Incheon\", \"Monterrey\", 960);"
let result = await db.exec(sql);
console.log(result);
await db.close();
} catch (err) {
console.error('Failed to load database:', err.message);
}
}
executeInsert();db.run(sqlString)Promise which resolves to an object with metadata but no results/data from the queryasync function runInsert() {
try {
let db = await getDBConnection(DB_NAME);
const sql = "INSERT INTO flights (origin, destination, duration) VALUES (\"Guatemala\", \"Dallas\", 180);"
let result = await db.run(sql);
console.log(result);
await db.close();
} catch (err) {
console.error('Failed to load database:', err.message);
}
}
runInsert();SELECT statement will be accessible
*async function extractData() {
try {
let db = await getDBConnection(DB_NAME);
const sql = "SELECT * FROM flights;"
let result = await db.all(sql);
result.forEach(flight => {
console.log(`Flight ${flight.id}, from ${flight.origin} to ${flight.destination} takes ${flight.duration} minutes.`)
});
await db.close();
} catch (err) {
console.error('Failed to load database:', err.message);
}
}
extractData();/flights that returns a JSON listing all the flights
Web Programming