How to Use Prepared Statements in MySQL with Node.js
Last Updated :
29 Aug, 2024
MySQL prepared a database by pre-compiling the SQL query with a set of placeholders for parameters. You could use the MySQL2 or MySQL library to be connected to your MySQL database and execute queries by passing the SQL statement with an array of values for the placeholders. It prevents SQL injection attacks by properly escaping the input from users and can often improve performance by allowing MySQL to reuse an execution plan for repeated queries with different parameters. Prepared statements become very useful in cases where either repeating or complex queries with dynamic data need to be executed.
Setting Up the Environment
Before looking at the prepared statements, let us set up the environment first:
Node.js: Download and install Node.js in your system from nodejs.org.
MySQL: Download and install MySQL. Then, create a database. You can download it from mysql.com.
Node.js MySQL Module: After this, you will need to install a Node.js module that gives you access to MySQL. You will need to run this line in your terminal:
npm install mysql
Connecting to MySQL from Node.js
You need to connect to the database to be able to use MySQL with Node.js. Here is how you can proceed:
JavaScript
onst mysql = require('mysql');
// Create a connection to database
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'your_database'
});
// Connect to database
connection.connect((err) => {
if (err) throw err;
console.log('Connected to the MySQL database!');
});
Using Prepared Statement
Now that you are connected to the database, you can start working with prepared statements in order to execute SQL queries safely.
Preparing a Statement
A prepared statement is created with placeholders – normally by ?. You would bind values to those placeholders when executing the statement.
JavaScript
// preparaing statement
const sql = 'SELECT * FROM users WHERE id = ?';
Executing a Prepared Statement
You can then execute this prepared statement by passing the SQL query and an array of values to the query method:
JavaScript
//excuting the prepared statement
const userId = 1;
connection.query(sql, [userId], (err, results) => {
if (err) throw err;
console.log(results);
});
In the above example, the userId is safely bound to the placeholder ?, preventing SQL injection.
Inserting Data Using Prepared Statements
Prepared statements can also be quite efficient when it comes to inserting data into the database. Here's an example:
JavaScript
// insert data into prepared statement
const insertSql = 'INSERT INTO users (name, email) VALUES (?, ?)';
const user = ['John Doe', '[email protected]'];
connection.query(insertSql, user, (err, results) => {
if (err) throw err;
console.log('User added with ID:', results.insertId);
});
The example herein has the user array holding values that are to be inserted in the name and email fields respectively.
Updating Data Using Prepared Statements
Statements can also be prepared to update records in the database. This is done as shown below:
JavaScript
//update data
const updateSql = 'UPDATE users SET email = ? WHERE id = ?';
const data = ['[email protected]', 1];
connection.query(updateSql, data, (err, results) => {
if (err) throw err;
console.log('Rows affected:', results.affectedRows);
});
This example will change the email of the user with an id equal to 1.
Deleting Data Using Prepared Statements
The prepared statements also enable safe deletion of records. For example:
JavaScript
// delete data
const deleteSql = 'DELETE FROM users WHERE id = ?';
const userIdToDelete = 1;
connection.query(deleteSql, [userIdToDelete], (err, results) => {
if (err) throw err;
console.log('Rows deleted:', results.affectedRows);
});
This statement deletes the user with id = 1 from the database.
Closing the Connection
After the required database operations are performed, the database connection needs to be closed:
JavaScript
//close the connection
connection.end((err) => {
if (err) throw err;
console.log('Database connection closed.');
});
Example of Parameterized Queries with Different Data Types
Parameterized queries are of great value for preventing SQL injection and guaranteeing database security. The next example show you how to use parameterized queries using different data types in Node.js, along with the mysql2 library.
Setup
Suppose that we have created a table, as follows, named employees in some database.
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER,
salary REAL,
is_active BOOLEAN
);
Example of Parameterized Queries
Install the MySQL2 Library
First, you need to install the mysql2 library. Open your terminal and run:
npm install mysql2
Set Up the MySQL Connection
Next, set up a connection to your MySQL database using the mysql2 library. Create a file named db.js and add the following code:
JavaScript
const mysql = require('mysql2');
// Create a connection to the database
const connection = mysql.createConnection({
host: 'localhost',
user: 'your-username',
password: 'your-password',
database: 'your-database-name'
});
// Connect to the database
connection.connect((err) => {
if (err) {
console.error('Error connecting to the database:', err.stack);
return;
}
console.log('Connected to the database as id', connection.threadId);
});
module.exports = connection;
Replace your-username, your-password, and your-database-name with your actual MySQL credentials.
Using Parameterized Queries
Now, let's see some examples of how to use parameterized queries to prevent SQL injection attacks.
a. Select Query with Parameters
JavaScript
const connection = require('./db');
// Sample parameters
const userId = 1;
// Parameterized query using ?
const sql = 'SELECT * FROM users WHERE id = ?';
connection.execute(sql, [userId], (err, results) => {
if (err) {
console.error('Error executing query:', err.stack);
return;
}
console.log('User details:', results);
});
In this example, ? is used as a placeholder for the userId parameter. The actual value is passed as an element of the array [userId] after the SQL string.
Insert Query with Parameters
JavaScript
const connection = require('./db');
// Sample data to insert
const name = 'John Doe';
const email = '[email protected]';
// Parameterized insert query
const sql = 'INSERT INTO users (name, email) VALUES (?, ?)';
connection.execute(sql, [name, email], (err, results) => {
if (err) {
console.error('Error inserting data:', err.stack);
return;
}
console.log('Data inserted successfully. Insert ID:', results.insertId);
});
This example inserts a new user into the users table using parameterized values for name and email.
Update Query with Parameters
JavaScript
const connection = require('./db');
// Sample data to update
const userId = 1;
const newEmail = '[email protected]';
// Parameterized update query
const sql = 'UPDATE users SET email = ? WHERE id = ?';
connection.execute(sql, [newEmail, userId], (err, results) => {
if (err) {
console.error('Error updating data:', err.stack);
return;
}
console.log('Data updated successfully. Affected Rows:', results.affectedRows);
});
This update query changes the email of a user with the specified userId.
Delete Query with Parameters
JavaScript
const connection = require('./db');
// Sample parameter
const userId = 1;
// Parameterized delete query
const sql = 'DELETE FROM users WHERE id = ?';
connection.execute(sql, [userId], (err, results) => {
if (err) {
console.error('Error deleting data:', err.stack);
return;
}
console.log('Data deleted successfully. Affected Rows:', results.affectedRows);
});
This delete query removes a user from the users table based on the userId.
Closing the Connection
Remember to close the database connection when your application terminates to avoid potential memory leaks:
JavaScript
connection.end((err) => {
if (err) {
console.error('Error ending the connection:', err.stack);
return;
}
console.log('Database connection closed.');
});
How to handle multiple queries using prepared statements within a single connection
Here’s how you can handle multiple queries using prepared statements within a single connection using the mysql2 library in Node.js.
Steps to Handle Multiple Queries Using Prepared Statements
Set Up Your Environment
Make sure Node.js is installed.
Install the mysql2 library using the command:
npm install mysql2
Create a Connection to MySQL
Use a single connection for all queries to manage resources efficiently. This connection can be reused across different operations.
JavaScript
const mysql = require('mysql2');
// Create a connection to the database
const connection = mysql.createConnection({
host: 'localhost',
user: 'your-username',
password: 'your-password',
database: 'your-database'
});
// Connect to the database
connection.connect((err) => {
if (err) {
console.error('Error connecting to the database:', err.message);
return;
}
console.log('Connected to the database.');
});
Replace 'your-username', 'your-password', and 'your-database' with your actual MySQL credentials.
Handling Multiple Queries Using Prepared Statements
You can use prepared statements with the connection.prepare() method. Here’s an example that inserts, updates, selects, and deletes records using prepared statements within a single connection.
JavaScript
// Prepare multiple queries as prepared statements
// 1. Insert multiple records
const insertStmt = connection.prepare(`
INSERT INTO employees (name, age, salary, is_active)
VALUES (?, ?, ?, ?)
`);
// 2. Update a record
const updateStmt = connection.prepare(`
UPDATE employees SET salary = ? WHERE name = ?
`);
// 3. Select active employees
const selectStmt = connection.prepare(`
SELECT * FROM employees WHERE is_active = ?
`);
// 4. Delete a record by ID
const deleteStmt = connection.prepare(`
DELETE FROM employees WHERE id = ?
`);
// Execute the prepared statements in sequence
connection.beginTransaction((err) => {
if (err) {
console.error('Error starting transaction:', err.message);
return;
}
// Insert records
const employees = [
["Alice Johnson", 28, 72000.00, true],
["Bob Smith", 35, 68000.00, true],
["Carol White", 40, 85000.00, false]
];
employees.forEach((employee) => {
insertStmt.execute(employee, (err, results) => {
if (err) {
console.error('Error inserting data:', err.message);
connection.rollback();
return;
}
console.log('Inserted:', results.insertId);
});
});
// Update salary
updateStmt.execute([75000.00, "Alice Johnson"], (err, results) => {
if (err) {
console.error('Error updating data:', err.message);
connection.rollback();
return;
}
console.log('Updated Rows:', results.affectedRows);
});
// Select active employees
selectStmt.execute([true], (err, rows) => {
if (err) {
console.error('Error fetching data:', err.message);
connection.rollback();
return;
}
console.log('Active Employees:', rows);
});
// Delete an employee
deleteStmt.execute([2], (err, results) => {
if (err) {
console.error('Error deleting data:', err.message);
connection.rollback();
return;
}
console.log('Deleted Rows:', results.affectedRows);
// Commit the transaction if everything was successful
connection.commit((err) => {
if (err) {
console.error('Error committing transaction:', err.message);
connection.rollback();
return;
}
console.log('Transaction committed successfully.');
});
});
});
// Close the prepared statements
insertStmt.unprepare();
updateStmt.unprepare();
selectStmt.unprepare();
deleteStmt.unprepare();
Closing the Connection
After completing all operations, you should close the database connection to free up resources:
JavaScript
connection.end((err) => {
if (err) {
console.error('Error closing the database connection:', err.message);
return;
}
console.log('Database connection closed.');
});
Explanation
- Prepared Statements: The connection.prepare() is used for the creation of prepared statements for various operations. They are executed further with dynamic values passed as arrays.
- Transactions: The connection.beginTransaction() initiates a transaction. If any of the queries fail, then connection.rollback() is called to undo all the changes made in that transaction. In the case where all queries succeed, then connection.commit() is called to save all changes.
- Error Handling: Each statement checks for errors and rolls back the transaction in case of an error. This ensures that the database remains consistent in case something goes wrong with one of the operations.
- Unprepare Statements: After the statements have been executed, the unprepare() call on each statement cleans up the prepared statement and frees resources.
Advantages of Prepared Statements
There are several advantages of using prepared statements in MySQL with Node.js:
- Security: It avoids SQL injection by separating SQL logic and data.
- Performance: It reduces the burden on parsing and compilation of the execution of SQL queries several times.
- Reusability: It will efficiently execute the executed SQL query with parameters only once.
Conclusion
The use of prepared statements in MySQL with Node.js is an extremely essential practice in building secure and efficient applications. Prepared statements avoid SQL injection by separating SQL logic safely from user data, and improve performance by reducing parsing and compilation time for SQL queries over and over again. Besides securing your database, using prepared statements in a Node.js project will also clean your code, hence make it more maintainable and scalable. It ensures that all of your interactions with the database are secure and optimized for applications to be more solid and reliable.
Similar Reads
How to Use PreparedStatement in Java?
A PreparedStatement is a pre-compiled SQL statement. It is a subinterface of Statement. Prepared Statement objects have some useful additional features than Statement objects. Instead of hard coding queries, PreparedStatement object provides a feature to execute a parameterized query. Advantages of
3 min read
How to Create and Use Stored Procedures in MySQL with Node.js?
Stored procedures in MySQL are very useful in the following ways Regarding the encapsulation of business logic within a database. They can be run multiple times and do not cause a large load on the client-server connection. In this tutorial, we will learn how to create and use stored procedures in M
3 min read
How to Use Transactions in MySQL with NodeJS?
Transactions in MySQL are used to execute a series of operations as a single unit of work, ensuring that all operations either succeed or fail together. This is crucial in maintaining data integrity, especially when dealing with complex operations that involve multiple database queries. In Node.js,
2 min read
How to Perform Complex Queries in MySQL with Node.js?
MySQL is a colleague relational database management system that is used for complex queries to deal with intricate data manipulation works. This guide is dedicated to teaching the reader more about making elaborate queries with the help of Node. js and the mysql2 package Once you have installed js y
3 min read
How to Use Connection Pooling with MySQL in Node.js?
MySQL is one of the most preferred relational databases, While Node.js is another name for JavaScript runtime environment. While assessing a large number of connections in the database in a Node. In this regard, effectiveness in managing them is also a significant determinant when developing and mai
3 min read
How to do pagination Node.js with MySQL ?
Node.js is a runtime environment like Chrome's V8 JavaScript engine. Node.js is an open-source, cross-platform, and backend runtime environment that executes outside a web browser. MySQL is an open-source relational database management system that is fast, reliable, flexible, and robust. Both MySQL
9 min read
How to Send JSON Response using Node.js ?
NodeJS is the runtime environment, which can execute the javascript code on any platform. It is widely used to create and run web application servers because of its salient features. During production, several times we need to send the resources or some type of information as a response, and javascr
5 min read
Node.js MySQL Update Statement
Node.js is an open-source platform for executing JavaScript code on the server-side. It can be downloaded from here. MySQL is an open-source Relational Database Management System (RDBMS) that uses Structured Query Language (SQL). It is the most popular language for adding, accessing, and managing co
2 min read
How To Use Node Modules with npm and package.json
NodeJS is a powerful runtime for server-side JavaScript & these modules are reusable pieces of code that can be easily imported and used in NodeJS applications. npm (Node Package Manager) is the default package manager for Node JS and is used to install, manage, and publish NodeJS packages. This
3 min read
How to Build a Simple Web Server with Node.js ?
Node.js is an open-source and cross-platform runtime environment for executing JavaScript code outside a browser. You need to remember that NodeJS is not a framework, and itâs not a programming language. Node.js is mostly used in server-side programming. In this article, we will discuss how to make
3 min read