PostgreSQL telah terhubung, dan kabar baiknya adalah keterampilan itu tidak berpindah jauh. MySQL — beserta turunannya MariaDB — adalah database client-server yang sama populernya, dipakai dari aplikasi web kecil hingga layanan berskala besar. Driver andalannya di ekosistem Node.js adalah package mysql2, dan meskipun tugasnya sama dengan pg, gaya API-nya memilih keputusan desain yang berbeda di beberapa titik penting. Chapter ini menyambungkan Node.js ke MySQL, lalu memetakan perbedaan-perbedaan tersebut agar kita luwes berpindah antar driver.
Menginstal Driver mysql2 #
Driver mysql2 dikembangkan di repositori node-mysql2
dan dipasang seperti biasa:
npm install mysql2API Promise dan Bentuk Hasilnya #
Paket mysql2 menawarkan dua pintu: mysql2 berbasis callback, dan mysql2/promise berbasis Promise. Kita langsung memakai yang kedua — cukup ganti jalur impor. Sebuah koneksi tunggal dibuat lewat createConnection, dan berbeda dari pg, function ini sekaligus melakukan penyambungan sehingga tidak ada panggilan connect() terpisah:
import mysql from 'mysql2/promise';
const conn = await mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
const [rows] = await conn.execute(
'SELECT id, judul FROM tugas WHERE selesai = ?',
[false]
);
console.log(rows);
await conn.end();Dua perbedaan mencolok langsung terlihat. Pertama, hasil execute() berbentuk array dua elemen [rows, fields] — baris data di elemen pertama, metadata kolom di elemen kedua — sehingga kita mendestruksinya dengan const [rows]. Kedua, placeholder MySQL memakai tanda tanya posisional ?, bukan penomoran $1 ala PostgreSQL. Parameter tetap dikirim terpisah dari teks SQL, sehingga keamanannya setara.
Peta Perbedaan pg dan mysql2 #
| Aspek | pg | mysql2 |
|---|---|---|
| Placeholder | $1, $2, … | ? |
| Bentuk hasil query | Object { rows, rowCount, ... } | Array [rows, fields] |
| Membuka koneksi | new Client() lalu await client.connect() | await mysql.createConnection(...) sekaligus |
| Menutup koneksi | await client.end() | await conn.end() |
| Konfigurasi target | Connection string satu URL | Object host, user, password, database |
| Pool | Class Pool | mysql.createPool(...) |
Table di atas adalah contekan yang layak ditempel di meja. Pola besar keduanya identik — sambungkan, kirim query berparameter, olas hasilnya, tutup — yang berubah hanya ejaan detailnya. Konfigurasi mysql2 memang lebih bertabur property karena MySQL tidak memiliki satu format connection string yang sestandar postgresql:// di kalangan tool-nya.
Kredensial dengan Berkas .env #
Sama seperti pada Chapter sebelumnya, kredensial database tidak ditulis di kode sumber. Berkas .env menampung konfigurasi koneksi dalam bentuk variabel lingkungan, lalu dimuat dengan flag --env-file:
DB_HOST=localhost
DB_PORT=3306
DB_USER=pengguna
DB_PASSWORD=YOUR_DATABASE_PASSWORD
DB_NAME=tugasdbnode --env-file=.env aplikasi.mjsBerkas Contoh Lengkap #
Berkas berikut memakai pool — dibuat dengan mysql.createPool dan opsi connectionLimit — untuk membuat tabel, menyisipkan satu baris, lalu membacanya:
// contoh-mysql.mjs — butuh server MySQL berjalan (tidak diuji di Course ini).
// Persiapan:
// 1. npm install mysql2
// 2. Buat berkas .env (lihat Chapter) lalu jalankan:
// node --env-file=.env contoh-mysql.mjs
import mysql from 'mysql2/promise';
const pool = mysql.createPool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT ?? 3306),
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 10,
});
async function main() {
await pool.query(`
CREATE TABLE IF NOT EXISTS tugas (
id INT AUTO_INCREMENT PRIMARY KEY,
judul VARCHAR(255) NOT NULL,
selesai BOOLEAN NOT NULL DEFAULT FALSE
)
`);
// API promise mengembalikan array [rows, fields].
const [hasil] = await pool.execute(
'INSERT INTO tugas (judul, selesai) VALUES (?, ?)',
['Belajar MySQL', false]
);
console.log('Tugas baru, id:', hasil.insertId);
const [rows] = await pool.execute('SELECT * FROM tugas ORDER BY id');
console.log('Daftar tugas:', rows);
await pool.end();
}
main().catch((error) => {
console.error('Koneksi atau query gagal:', error.message);
process.exit(1);
});Beberapa detail MySQL yang baru di sini perlu dijelaskan. Tipe INT AUTO_INCREMENT PRIMARY KEY adalah padanan SERIAL di PostgreSQL: server menomori baris baru secara otomatis. Setelah INSERT, id yang diberikan server tersedia di hasil.insertId — padanan lastInsertRowid pada node:sqlite dan RETURNING pada pg. Kolom teks memakai VARCHAR(255) dengan batas panjang eksplisit, dan nilai boolean dikonversi MySQL menjadi 1 atau 0 saat baris dibaca kembali.
Dua driver client-server kini telah kita kendalikan, dan keduanya berulang kali menyinggung satu frasa yang sama: parameter terikat. Frasa itu adalah garis batas antara aplikasi yang selamat dan aplikasi yang bisa dibongkar orang luar lewat input jahat. Saatnya kita bedah mengapa dan bagaimana — pada Chapter Query Parameterized.