作为 CRUD 工程师,这种基本功自然不会忘记,但是用到的时候直接复制岂不美哉?
pgSQL 这边提供了两个对象来实现数据库连接,分别是 Pool
和 Client
,这里我们只谈论 Pool
,因为它更符合我的业务逻辑
yarn add pg
yarn add @types/pg # if use TypeScript
首先,你需要准备好连接信息,需要地址、端口、用户、密码、数据库,相信这个不用我多BB。
我们再来实现一个最简实现:
import { Pool } from "pg";
const pool = new Pool();
所以,连接信息呢?然而这段代码是完全合法的,因为 pg 库会先找你在 new Pool()
中传的参数,如果找不到就找环境变量,还找不到就用默认值,各个值的对应关系如下表:
项目 | 环境变量 | 默认值 |
---|---|---|
地址 | PGHOST | localhost |
用户 | PGUSER | USER(环境变量) |
密码 | PGPASSWORD | (空) |
数据库 | PGUSER | USER(环境变量) |
端口 | PGPORT | 5432 |
如果你正在调试一个开源项目,又不想每次调试前都要写一堆 PGHOST=......PGPORT=5432
,更不想把这么一堆的写进电脑的环境变量里(当然,这也并不安全),也是有法子的,这个叫 dotenv
的包能解决这个问题
yarn add dotenv
import 'dotenv/config'
然后就能在运行 js 脚本的时候自动导入项目目录下的 .env
文件,并设置环境变量。
当然,这一切让你觉得麻烦的话,也可以直接把连接信息写死在 new Pool()
里
import { Pool } from 'pg'
const pool = new Pool({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
})
直接查询还是非常简单的
pool.query('select now()',(err,result) => {
if (err) throw err.stack
console.log(result.rows[0])
})
(err,result)
这个回调可以不写,然后就会输出当前的时间,这是直接查询,我们接着看 Prepare Statement。
Prepare Statement,听着高端,其实干的就一件事,检查一下输入有没有不合法内容,然后拼接字符串,仅此而已,但是这确实是刚需,因为你不能相信用户的输入,用户可能会在输入里写各种离谱玩意,直接给你删库了就好玩了,所以还是得老老实实地用这个。
const query = {
name: "fetch-user",
text: `INSERT INTO zhutian.web_content (name, link, category, cover)
VALUES ($1::varchar, $2::varchar, $3::varchar, $4::varchar)`,
values: [post.title, post.url, post.category, post.image],
};
pool.query(query);
语法上,直接在 query 对象的 text 值里头直接插入形如$1,$2,$3
这样的东西,然后我们在 values 那里写一个列表,列表对应的值跟$1
这些一一对应。
同样的,我们可以在 query 后面加上回调,但是这里没必要。
pg 库会自己断开 Pool 的连接,如果实在有刚需,那就 pool.end()
heroku 提供的免费 Postgres 数据库限制一定要加密访问,但是证书偏偏是自签的,Node 那边自检过不去,虽然 pg 库提供了验证自签证书的参数,但是我没学过相关知识,所以就禁用咯。
// 直接写在 .env 里倒是也行,但是有时候 ci 工具会因此抽风,比如 Vercel,所以还是写文件里好
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
const pool = new Pool({ ssl:true })
非常简单,一点坑都没
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
database : 'test'
});
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end()
MySQL 没坑,但是 Serverless 有坑,如果像之前那么写的话,Serverless 函数就会出问题,第一次卡住不输出,第二次函数崩溃,当时的 log 实在找不到了,就简单在这记录下咋解决的吧。
首先,每次 Serverless 请求都要独占一个 connection,而且用完立刻销毁,这样 Serverless 函数才正常,简单上个代码。
var mysql = require('mysql');
// 写个函数,执行一次返回一个新连接
function getConnection() {
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '123456',
database : 'test'
})
return connection
}
// 示例函数
export default async function () {
let connection = getConnection()
// Some Logic
connection.end()
return;
}