Topik ini membahas cara menyambungkan MySQL dari kode aplikasi melalui driver resminya pada tiga bahasa yang umum dipakai pada aplikasi web, yaitu PHP dengan PDO, Python dengan pymysql, dan Node.js dengan mysql2. Pembahasan mencakup peran driver, parameter koneksi yang wajib diberikan, serta program utuh yang membuka koneksi, menjalankan satu query, mencetak hasilnya, lalu menutup koneksi. Setelah menyelesaikannya, basis data latihan yang sama dapat diakses dari ketiga bahasa tersebut dengan pola yang serupa.
Peran driver dan parameter koneksi#
Aplikasi tidak membaca berkas data MySQL secara langsung. Proses mysqld melayani seluruh permintaan data melalui protokol koneksi miliknya sendiri, sehingga kode aplikasi memerlukan perantara untuk mengirim query dan menerima hasilnya. Perantara itu disebut driver, yaitu library yang menerjemahkan pemanggilan fungsi pada bahasa pemrograman menjadi pesan protokol MySQL. Setiap bahasa memiliki driver andalannya, dan tabel berikut merangkum yang digunakan pada topik ini.
| Bahasa | Driver | Keterangan |
|---|---|---|
| PHP | PDO dengan driver pdo_mysql | Antarmuka berorientasi objek yang juga mendukung basis data lain, dengan mysqli sebagai alternatif |
| Python | pymysql | Ditulis murni dengan Python sehingga tidak memerlukan kompilasi, dengan Connector/Python sebagai alternatif resmi Oracle |
| Node.js | mysql2 | Kelanjutan dari paket node-mysql dengan dukungan Promise bawaan |
Sebuah koneksi didefinisikan oleh sekelompok parameter, yaitu host yang menyatakan alamat server, port yang menyatakan pintu layanannya, user dan password untuk autentikasi, serta database yang dipilih sejak awal. Pada seluruh contoh topik ini, host diisi 127.0.0.1 sehingga koneksi berjalan melalui TCP loopback. Nilai localhost tidak selalu berarti hal yang sama karena sebagian driver memakainya sebagai isyarat untuk menggunakan socket Unix pada mesin yang sama. Agar perilaku contoh selalu dapat direproduksi, 127.0.0.1 digunakan secara konsisten.
Menyiapkan basis data latihan#
Basis data latihan dibangun ulang dari keadaan kosong di awal topik agar keluaran setiap program dapat direproduksi. Basis data perpustakaan berisi satu tabel anggota dengan empat baris data. Perintah berikut menjalankan tugas tersebut melalui klien mysql dalam mode batch.
# menyiapkan basis data latihan dari keadaan kosong
mysql -u root -e "DROP DATABASE IF EXISTS perpustakaan;"
mysql -u root -e "CREATE DATABASE perpustakaan;"
mysql -u root perpustakaan <<'SQL'
CREATE TABLE anggota (
id INT PRIMARY KEY,
nama VARCHAR(60) NOT NULL,
kota VARCHAR(40) NOT NULL
);
INSERT INTO anggota (id, nama, kota) VALUES
(1, 'Ali', 'Bandung'),
(2, 'Budi', 'Semarang'),
(3, 'Citra', 'Surabaya'),
(4, 'Dewi', 'Yogyakarta');
SQLHeredoc <<'SQL' mengirim pernyataan pembuatan tabel dan pengisian datanya sebagai masukan klien. Klien tidak mencetak apa pun ketika seluruh pernyataannya berhasil, sehingga keberhasilan penyiapan ini diuji oleh program-program pada bagian berikutnya. Query pada ketiga program selalu memakai ORDER BY id, sehingga urutan keluarannya dapat dipastikan.
Menyambung dari PHP dengan PDO#
PDO (PHP Data Objects) adalah antarmuka berorientasi objek untuk mengakses basis data pada PHP. Nama basis data yang dituju tidak diberikan sebagai parameter biasa, melainkan di dalam DSN (data source name), yaitu string yang diawali nama driver lalu menyebut host, port, nama basis data, dan charset. Berkas berikut menunjukkan pola lengkapnya, mulai dari pembukaan koneksi sampai penutupannya.
// tidak-dijalankan
<?php
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=perpustakaan;charset=utf8mb4";
try {
$pdo = new PDO($dsn, "root", null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$hasil = $pdo->query("SELECT id, nama, kota FROM anggota ORDER BY id");
foreach ($hasil as $baris) {
echo $baris["id"], " ", $baris["nama"], " ", $baris["kota"], PHP_EOL;
}
$pdo = null;
} catch (PDOException $e) {
echo "Koneksi gagal: ", $e->getMessage(), PHP_EOL;
}Opsi PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION membuat PDO melaporkan kegagalan dengan melempar exception, alih-alih diam dan mengembalikan nilai false. Perilaku bawaan yang diam ini sulit didiagnosis, sehingga opsi tersebut hampir selalu dinyalakan. Kegagalan koneksi maupun kegagalan query kemudian ditangkap satu blok try/catch yang mencetak pesan errornya.
Koneksi PDO ditutup dengan mengosongkan variabel yang memegang objeknya, karena PHP menutup koneksi ketika objek PDO dihapus dari memori. Pada skrip pendek, langkah ini dapat ditinggalkan karena koneksi ikut tertutup saat skrip berakhir. Untuk nilai yang berasal dari masukan pengguna, query disusun dengan prepare() dan bukan query(). Mekanismenya dijelaskan pada topik Query Berparameter di modul ini.
Menyambung dari Python dengan pymysql#
pymysql adalah driver MySQL untuk Python yang ditulis murni dengan Python, sehingga pemasangannya cukup dengan pip install pymysql tanpa kompilasi tambahan. Koneksi dibuka dengan pymysql.connect() yang menerima parameter koneksi sebagai argumen bernama. Hasil query dibaca melalui objek kursor, yaitu perantara yang mengirim pernyataan dan mengambil baris hasilnya.
# tidak-dijalankan
import pymysql
koneksi = pymysql.connect(
host="127.0.0.1",
port=3306,
user="root",
password="",
database="perpustakaan",
)
try:
with koneksi.cursor() as kursor:
kursor.execute("SELECT id, nama, kota FROM anggota ORDER BY id")
for id_anggota, nama, kota in kursor.fetchall():
print(id_anggota, nama, kota)
finally:
koneksi.close()Metode kursor.fetchall() mengembalikan seluruh baris hasil, yang kemudian dicetak satu per satu. Blok try/finally memastikan koneksi.close() tetap dipanggil meskipun terjadi error di tengah jalan, karena koneksi yang dibiarkan terbuka menghabiskan jatah koneksi server. Pemanggilan skripnya dilakukan seperti berikut.
# menjalankan program koneksi dari Python
python3 koneksi.py1 Ali Bandung
2 Budi Semarang
3 Citra Surabaya
4 Dewi YogyakartaKeempat baris keluaran sama persis dengan isi tabel anggota, terurut menurut id. Seluruh proses hanya mengirim satu query dan mencetak hasilnya, sehingga keluaran tersebut sepenuhnya berasal dari server.
Menyambung dari Node.js dengan mysql2#
mysql2 adalah driver Node.js yang menjadi kelanjutan dari paket node-mysql dengan tambahan dukungan Promise. Submodul mysql2/promise menyediakan API berbasis Promise sehingga alurnya ditulis dengan async/await. Karena Node.js mengeksekusi kode secara asinkron, seluruh proses koneksi dan query dibungkus dalam satu fungsi asinkron.
// tidak-dijalankan
const mysql = require("mysql2/promise");
async function utama() {
const koneksi = await mysql.createConnection({
host: "127.0.0.1",
port: 3306,
user: "root",
password: "",
database: "perpustakaan",
});
try {
const [baris] = await koneksi.query(
"SELECT id, nama, kota FROM anggota ORDER BY id"
);
for (const data of baris) {
console.log(`${data.id} ${data.nama} ${data.kota}`);
}
} finally {
await koneksi.end();
}
}
utama();Metode koneksi.query() mengembalikan pasangan berisi array baris dan informasi kolom, dan pasangan itu dipecah langsung pada baris const [baris] = .... Penutupan koneksi dilakukan dengan koneksi.end() di dalam blok finally dengan alasan yang sama seperti pada versi Python. Berikut pemanggilannya.
# menjalankan program koneksi dari Node.js
node koneksi.js1 Ali Bandung
2 Budi Semarang
3 Citra Surabaya
4 Dewi YogyakartaKeluaran Node.js identik dengan keluaran Python karena keduanya mengeksekusi query yang sama pada data yang sama. Perbedaan ketiga contoh hanya terletak pada tata bahasanya, sedangkan urutan langkahnya sama, yaitu membuka koneksi, mengirim query, mencetak hasil, lalu menutup koneksi.
Kesalahan umum#
Basis data tujuan tidak ditemukan. Driver melaporkan error ER_BAD_DB_ERROR apabila nama basis data pada parameter koneksi salah ketik atau memang belum dibuat. Contoh berikut menyambung ke perpustakaanx, sedangkan basis data yang ada bernama perpustakaan.
# menyambung dengan nama basis data yang salah
node <<'JS'
const mysql = require("mysql2/promise");
mysql.createConnection({ host: "127.0.0.1", user: "root", database: "perpustakaanx" })
.catch((err) => console.error(err.code, "-", err.message));
JSER_BAD_DB_ERROR - Unknown database 'perpustakaanx'Perbaikannya adalah meluruskan nama basis data pada parameter koneksi atau membuatnya lebih dahulu dengan CREATE DATABASE.
Akun tidak dikenal atau kata sandi salah. Server menolak koneksi dengan error 1045 apabila kombinasi user dan password tidak cocok dengan akun yang terdaftar. Contoh berikut memakai user apoteker yang tidak ada di server.
# menyambung dengan akun yang tidak terdaftar
python3 <<'PY'
import pymysql
try:
pymysql.connect(host="127.0.0.1", user="apoteker")
except pymysql.err.OperationalError as err:
print(err)
PY(1045, "Access denied for user 'apoteker'@'localhost' (using password: NO)")Pesan error menyebut akun yang dicoba beserta host asalnya, beserta keterangan bahwa koneksi tidak mengirim kata sandi apa pun. Perbaikannya adalah menggunakan akun yang benar, menuliskan kata sandinya, atau mendaftarkan akun baru di server.
Koneksi dibiarkan terbuka sampai program berakhir. Pada program yang berjalan lama dan melayani banyak permintaan, kebiasaan ini menghabiskan jatah koneksi server yang jumlahnya dibatasi variabel max_connections. Biasakan menutup koneksi dalam blok finally, dan gunakan pool koneksi untuk aplikasi yang menerima permintaan beruntun sebagaimana dijelaskan pada topik Connection Pooling di modul ini.
Ringkasan#
- Driver menerjemahkan pemanggilan fungsi bahasa pemrograman menjadi protokol koneksi MySQL, dan topik ini memakai PDO untuk PHP, pymysql untuk Python, serta mysql2 untuk Node.js.
- Parameter koneksi terdiri atas
host,port,user,password, dandatabase, dengan127.0.0.1agar koneksi selalu berjalan melalui TCP. - Pola ketiga contoh sama, yaitu membuka koneksi, mengirim query, mencetak hasil, lalu menutup koneksi dalam blok
finallyatau dengan mengosongkan objek PDO. - Error koneksi yang paling sering adalah basis data tidak ditemukan (
ER_BAD_DB_ERROR) dan autentikasi ditolak (error 1045).
Referensi#
- MySQL Connectors and APIs — Oracle — Daftar resmi konektor MySQL untuk PHP, Python, Node.js, dan bahasa lainnya.
- PDO_MYSQL DSN — The PHP Group — Format DSN PDO untuk MySQL beserta atribut koneksi yang didukung.
- PyMySQL Documentation — PyMySQL Project
— Referensi
pymysql.connect()dan penggunaan kursor. - mysql2 — npm — Dokumentasi paket mysql2, termasuk API berbasis Promise-nya.
- Connecting to the MySQL Server — Oracle — Parameter koneksi dan proses autentikasi di sisi server.