Node.js + MySQL холбох
Node.js аппликейшнаас MySQL өгөгдлийн сантай харилцахын тулд mysql2 package ашиглана. Энэ хичээлд connection pool, prepared statement, async/await query бичих аргыг сурна.
mysql2 суулгах
npm install mysql2
mysql2 нь mysql package-ийн сайжруулсан хувилбар бөгөөд Promise дэмжих, prepared statement-ийн найдвартай хэрэгжилттэй.
Энгийн холболт
const mysql = require("mysql2/promise");
async function main() {
const connection = await mysql.createConnection({
host: "localhost",
user: "root",
password: "нууц_үг",
database: "myshop",
});
const [rows] = await connection.execute("SELECT * FROM users");
console.log(rows);
await connection.end();
}
main();
mysql2/promise импортолж байгаа нь async/await синтакс ашиглах боломж олгоно.
Connection Pool — зөв арга
Аппликейшн дотор query бүрт шинэ холболт нээх, хаах нь удаан бөгөөд нөөц их зарцуулна. Үүний оронд connection pool ашиглана — урьдчилан тогтоосон тооны холболтыг дахин дахин ашиглана.
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'нууц_үг',
database: 'myshop',
waitForConnections: true,
connectionLimit: 10, -- нэгэн зэрэг хамгийн ихдээ 10 холболт
queueLimit: 0 -- хүлээлгийн дараалалд хязгааргүй
});
module.exports = pool;
connectionLimit: 10 гэдэг нь нэгэн зэрэг 10 query зэрэг ажиллах боломжтой гэсэн үг.
Pool ашиглан query хийх
const pool = require('./db'); -- дээрх pool файлаас импортолно
async function getAllUsers() {
const [rows] = await pool.execute('SELECT * FROM users');
return rows;
}
async function getUserById(id) {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[id]
);
return rows[0]; -- нэг мөр буцаана
}
async function main() {
const users = await getAllUsers();
console.log('Бүх хэрэглэгч:', users);
const user = await getUserById(1);
console.log('ID=1 хэрэглэгч:', user);
}
main();
Prepared Statement — SQL Injection-оос хамгаалах
Хэрэглэгчийн оролтыг query-д шууд залгах нь аюултай:
-- БУРУУ — SQL Injection-д өртөмтгий!
const name = req.body.name;
const query = `SELECT * FROM users WHERE name = '${name}'`;
Хэрэглэгч name-д ' OR '1'='1 оруулбал бүх хэрэглэгчийн мэдээллийг харах боломжтой болно.
Зөв арга — ? placeholder ашиглах:
-- ЗӨВ — prepared statement
async function findUserByName(name) {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE name = ?',
[name] -- mysql2 автоматаар аюулгүй болгоно
);
return rows;
}
? тэмдэглэгч бүрт утгыг хоёрдугаар аргументийн массиваас дарааллаар нь авна:
async function createUser(name, email, password) {
const [result] = await pool.execute(
'INSERT INTO users (name, email, password) VALUES (?, ?, ?)',
[name, email, password]
);
return result.insertId; -- шинэ мөрийн ID буцаана
}
CRUD үйлдлүүд
Мэдээлэл нэмэх
async function createProduct(name, price, stock) {
const [result] = await pool.execute(
"INSERT INTO products (name, price, stock) VALUES (?, ?, ?)",
[name, price, stock],
);
console.log("Шинэ бараа ID:", result.insertId);
console.log("Нэмэгдсэн мөрийн тоо:", result.affectedRows);
return result.insertId;
}
Мэдээлэл хайх
async function searchProducts(keyword) {
const [rows] = await pool.execute(
"SELECT * FROM products WHERE name LIKE ?",
[`%${keyword}%`],
);
return rows;
}
Мэдээлэл өөрчлөх
async function updatePrice(productId, newPrice) {
const [result] = await pool.execute(
"UPDATE products SET price = ? WHERE id = ?",
[newPrice, productId],
);
if (result.affectedRows === 0) {
throw new Error("Бараа олдсонгүй");
}
return true;
}
Мэдээлэл устгах
async function deleteUser(userId) {
const [result] = await pool.execute("DELETE FROM users WHERE id = ?", [
userId,
]);
return result.affectedRows > 0;
}
Transaction
async function placeOrder(userId, items) {
const conn = await pool.getConnection();
try {
await conn.beginTransaction();
-- Захиалга үүсгэх
const [orderResult] = await conn.execute(
'INSERT INTO orders (user_id, total) VALUES (?, 0)',
[userId]
);
const orderId = orderResult.insertId;
let total = 0;
-- Захиалгын мөрүүд нэмэх
for (const item of items) {
await conn.execute(
'INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (?, ?, ?, ?)',
[orderId, item.productId, item.quantity, item.price]
);
total += item.quantity * item.price;
}
-- Нийт дүн шинэчлэх
await conn.execute(
'UPDATE orders SET total = ? WHERE id = ?',
[total, orderId]
);
await conn.commit();
return orderId;
} catch (err) {
await conn.rollback();
throw err;
} finally {
conn.release(); -- pool-д буцаана
}
}
Бүтэн жишээ: Express API
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
app.use(express.json());
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'нууц_үг',
database: 'myshop',
connectionLimit: 10
});
-- Бүх бараа авах
app.get('/products', async (req, res) => {
try {
const [rows] = await pool.execute('SELECT * FROM products');
res.json(rows);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
-- Нэг бараа авах
app.get('/products/:id', async (req, res) => {
try {
const [rows] = await pool.execute(
'SELECT * FROM products WHERE id = ?',
[req.params.id]
);
if (rows.length === 0) {
return res.status(404).json({ error: 'Бараа олдсонгүй' });
}
res.json(rows[0]);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
-- Бараа нэмэх
app.post('/products', async (req, res) => {
const { name, price, stock } = req.body;
try {
const [result] = await pool.execute(
'INSERT INTO products (name, price, stock) VALUES (?, ?, ?)',
[name, price, stock]
);
res.status(201).json({ id: result.insertId });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.listen(3000, () => console.log('Сервер ажиллаж байна: 3000'));
Алдаа зохицуулах
async function safeQuery(sql, params = []) {
try {
const [rows] = await pool.execute(sql, params);
return { data: rows, error: null };
} catch (err) {
console.error("MySQL алдаа:", err.message);
return { data: null, error: err.message };
}
}
--Ашиглах;
const { data, error } = await safeQuery("SELECT * FROM users WHERE id = ?", [
userId,
]);
if (error) {
console.log("Алдаа гарлаа:", error);
} else {
console.log("Хэрэглэгч:", data[0]);
}
Дараагийн хичээлд:
Python + MySQL холболт — mysql-connector-python package, cursor, parameterized query ашиглах аргыг үзнэ.