Node.js + PostgreSQL
Та одоо PostgreSQL-н нарийн ойлголтуудыг бүгдийг эзэмшлээ. Ирээдүйд та эдгээрийг JavaScript application-аасаа ашиглах хэрэгтэй болно. Энэ хичээлд хамгийн нийтлэг pg (node-postgres) library-г ашиглан Node.js-аас PostgreSQL-тай холбогдох, аюулгүй асуулга ажиллуулах, transaction гүйцэтгэх аргуудыг сурна.
Суулгалт ба холболт
# Шинэ Node.js төсөл үүсгэх
mkdir pg-demo && cd pg-demo
npm init -y
npm install pg
npm install dotenv # нууц мэдээллийг .env-д хадгалах
// db.js — connection pool тохиргоо
import pg from 'pg';
import 'dotenv/config';
const { Pool } = pg;
// Pool нь олон холболтыг удирдаж, дахин ашигладаг
export const pool = new Pool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT) || 5432,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 10, // Нэгэн зэрэг хамгийн ихдээ 10 холболт
idleTimeoutMillis: 30000, // 30 секунд идэвхгүй байвал холболт хаах
connectionTimeoutMillis: 2000,
});
// Холболт шалгах
pool.on('error', (err) => {
console.error('PostgreSQL холболтын алдаа:', err);
});
# .env файл
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
DB_PASSWORD=нууцүг123
Үндсэн асуулгууд
$1, $2 гэсэн parameterized query ашиглах нь SQL injection халдлагаас хамгаалдаг. Хэзээ ч string concatenation ашиглаж SQL үүсгэж болохгүй.
// queries.js
import { pool } from './db.js';
// Бүх хэрэглэгчдийг авах
export async function getAllUsers() {
const result = await pool.query(
'SELECT id, username, email, created_at FROM users ORDER BY created_at DESC'
);
return result.rows; // массив буцаана
}
// ID-аар нэг хэрэглэгч авах
export async function getUserById(id) {
const result = await pool.query(
'SELECT id, username, email FROM users WHERE id = $1',
[id] // параметрийг тусад нь дамжуулах — SQL injection болохгүй
);
return result.rows[0] ?? null; // нэг мөр буюу null
}
// Шинэ хэрэглэгч үүсгэх
export async function createUser(username, email) {
const result = await pool.query(
`INSERT INTO users (username, email, created_at)
VALUES ($1, $2, NOW())
RETURNING id, username, email, created_at`,
[username, email]
);
return result.rows[0];
}
// Хэрэглэгч шинэчлэх
export async function updateUser(id, username) {
const result = await pool.query(
'UPDATE users SET username = $1 WHERE id = $2 RETURNING *',
[username, id]
);
return result.rows[0] ?? null;
}
// Хэрэглэгч устгах
export async function deleteUser(id) {
const result = await pool.query(
'DELETE FROM users WHERE id = $1 RETURNING id',
[id]
);
return result.rowCount > 0; // устгагдсан уу?
}
Transaction ажиллуулах
Node.js-аас transaction хийхдээ pool.connect() ашиглан нэг холболт авч, тухайн холболт дээр бүх үйлдлийг гүйцэтгэнэ:
// transaction.js
import { pool } from './db.js';
export async function transferFunds(fromId, toId, amount) {
const client = await pool.connect(); // холболт авах
try {
await client.query('BEGIN');
// Хасах
const debit = await client.query(
'UPDATE accounts SET balance = balance - $1 WHERE id = $2 RETURNING balance',
[amount, fromId]
);
if (debit.rows[0].balance < 0) {
throw new Error('Дансны үлдэгдэл хүрэлцэхгүй байна');
}
// Нэмэх
await client.query(
'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
[amount, toId]
);
await client.query('COMMIT');
return { success: true };
} catch (error) {
await client.query('ROLLBACK');
throw error; // дээш дамжуулах
} finally {
client.release(); // заавал pool-д буцааж өгөх
}
}
Pagination ба хайлт
// Pagination ба хайлттай жагсаалт
export async function searchProducts({ query = '', page = 1, limit = 20 }) {
const offset = (page - 1) * limit;
const result = await pool.query(
`SELECT
id, name, price, category,
COUNT(*) OVER () AS нийт_тоо
FROM products
WHERE name ILIKE $1
ORDER BY name
LIMIT $2 OFFSET $3`,
[`%${query}%`, limit, offset]
);
const total = result.rows[0]?.нийт_тоо ?? 0;
return {
items: result.rows,
total: Number(total),
page,
totalPages: Math.ceil(total / limit),
};
}
Холболтыг зөв хаах
// main.js — програм дуусах үед pool-г хаах
import { pool } from './db.js';
import { getAllUsers, createUser } from './queries.js';
async function main() {
try {
// Хэрэглэгч үүсгэх
const user = await createUser('bold_mn', 'bold@example.mn');
console.log('Үүсгэлээ:', user);
// Жагсаалт авах
const users = await getAllUsers();
console.log('Нийт хэрэглэгч:', users.length);
} finally {
// Програм дуусахад pool-г заавал хаах
await pool.end();
}
}
main().catch(console.error);
pg library нь хялбар бөгөөд хяналттай. Илүү дэвшилтэт ORM хэрэгтэй бол Prisma эсвэл Drizzle ORM нь PostgreSQL-г маш сайн дэмждэг — гэхдээ тэдгээрийн ард pg л ажиллаж байдаг.
Дараагийн хичээлд:
Курсийн бүх мэдлэгийг нэгтгэн ашиглах эцсийн төсөл — Node.js REST API + PostgreSQL database бүтэн систем бариулна.