紀錄一下這三個語言對 MySQL 做 CRUD 的方法當作筆記用,不會使用 ORM 或者其他功能強大複雜的套件,畢竟如果有使用 framework 通常都有附,這邊使用最簡潔的方法完成。
MySQL
先建立表單來做 CRUD 使用。
CREATE TABLE `examples` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`created_at` DATETIME NOT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_unicode_ci';
PHP - PDO
PHP 現在一定是使用 PDO,實做方式如下。
<?php
$username = 'root';
$password = 123456;
try {
$name = 'Chan';
$createdAt = date('Y-m-d H:i:s');
// 設定
$dbh = new \PDO('mysql:host=localhost;dbname=demo;charset=utf8', $username, $password);
// 寫入
$sql = "INSERT INTO `examples` (`name`, `created_at`) VALUES (:name, :created_at)";
$sth = $dbh->prepare($sql);
$sth->bindParam(':name', $name, \PDO::PARAM_STR);
$sth->bindParam(':created_at', $createdAt, \PDO::PARAM_STR);
$sth->execute();
// 提取多筆
$sql = "SELECT * FROM `examples`";
$sth = $dbh->prepare($sql);
$sth->execute();
$rows = $sth->fetchAll(\PDO::FETCH_ASSOC);
var_dump($sth->rowCount());
var_dump($rows);
// 提取單筆
$sql = "SELECT * FROM `examples`";
$sth = $dbh->prepare($sql);
$sth->execute();
$rows = $sth->fetch(\PDO::FETCH_ASSOC);
var_dump($rows);
} catch (Exception $e) {
var_dump($e-getMessage());
} finally {
$sth = null;
$dbh = null;
}
其中 PDO::PARAM_STR
的部份是讓你確定傳入文字的型別,可以有效防止 SQL Injection,常使用的有:
- PDO::PARAM_STR
- PDO::PARAM_INT
- PDO::PARAM_BOOL
其他可以使用的部份可以看這邊,更新跟刪除的部份就是把 INSERT 的內容改成 UPDATE
跟 DELETE
,就不多寫範例了。
Python - MySQLdb
Python 我們使用 MySQLdb
來操作,怎麼安裝網路上有很多教學,這邊也不示範了。
# -*- coding: utf-8 -*-
import MySQLdb
import datetime
username = 'root'
password = '123456'
try:
# 設定
db = MySQLdb.connect(host='localhost', db='demo', user=username, passwd=password)
cursor = db.cursor()
# 寫入
values = (
'Chan',
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
sql = "INSERT INTO `examples` (`name`, `created_at`) VALUES (%s, %s)"
cursor.execute(sql, values)
db.commit()
# 提取多筆
sql = "SELECT * FROM `examples`"
cursor.execute(sql)
rows = cursor.fetchall()
print(cursor.rowcount)
print(rows)
# 提取單筆
sql = "SELECT * FROM `examples`"
cursor.execute(sql)
row = cursor.fetchone()
print(row)
except Exception as e:
print(str(e))
finally:
db.close()
這個套件沒有回傳 key name,所以如果你想要對應欄位名稱的話可能要這樣使用
# 提取多筆
sql = "SELECT * FROM `examples`"
cursor.execute(sql)
rows = cursor.fetchall()
for row in rows:
pk, name, date = row
print(pk)
print(name)
print(date)
此套件傳遞參數的方法很多,可以參考 Python best practice and securest to connect to MySQL and execute queries 這篇。
Node.js - mysql2
node.js 部份我選用了 mysql2,他語法基本上跟 mysql 一樣,多了些功能跟據說效能有提昇,我是沒實測,但就用最新的。
const mysql = require('mysql2');
const datetime = require('node-datetime');
try {
// 設定
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
database: 'demo'
});
// 寫入
const name = 'Chan';
const dt = datetime.create();
const createdAt = dt.format('Y-m-d H:M:S');
let sql = 'INSERT INTO `examples` (`name`, `created_at`) VALUES (?, ?)';
connection.execute(sql, [name, createdAt], (err, rows, fields) => {
if (err) {
console.log(err);
}
});
// 讀取
sql = 'SELECT * FROM `examples`';
connection.execute(sql, (err, rows, fields) => {
console.log(rows);
});
connection.end();
} catch (e) {
console.log(e.message);
}
這個套件沒有封裝多筆或單筆的功能,要取單筆就是拿取陣列第一筆資料,上面的程式碼是 sync 模式執行的,所以其實是有機會讀到沒寫入的資料,除非你使用 callback 或 promise,示範一下 promise 的作法。
const mysql = require('mysql2/promise');
const datetime = require('node-datetime');
async function main() {
try {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
database: 'demo'
});
// 寫入
const name = 'Chan';
const dt = datetime.create();
const createdAt = dt.format('Y-m-d H:M:S');
let sql = 'INSERT INTO `examples` (`name`, `created_at`) VALUES (?, ?)';
await connection.execute(sql, [name, createdAt]);
// 讀取
sql = 'SELECT * FROM `examples`';
const [rows] = await connection.execute(sql);
console.log(rows);
connection.end();
} catch (e) {
console.log(e.message);
}
}
main();
沒有留言:
張貼留言