前言
查看mysql2源码可以看到连接数据库有两种方法,一种是createConnection
,另一种是createPool
。
为啥不只提供一种链接方式呢?
-
在开发web应用程序时,连接池是一个很重要的概念。建立一个数据库连接所消耗的性能成本是很高的。在服务器应用程序中,如果为每一个接收到的客户端请求都建立一个或多个数据库连接,将严重降低应用程序性能。
-
因此在服务器应用程序中通常需要为多个数据库连接创建并维护一个连接池,当连接不再需要时,这些连接可以缓存在连接池中,当接收到下一个客户端请求时,从连接池中取出连接并重新利用,而不需要再重新建立连接。
-
所以既有
createConnection
创建数据库连接、createPool
创建数据库池和createPoolCluster
创建数据库池群几种方式连接数据库
咱主要介绍createConnection
和createPool
config
import { PoolOptions } from "mysql2";
export const config = {
DATABASE: 'admin_auth', //数据库名称
USERNAME: 'root', //mysql用户名
PASSWORD: 'password', //mysql密码
PORT: 3306, //mysql端口号
HOST: 'localhost' //服务器ip
}
export const mysqlAccess: PoolOptions = {
host: config.HOST,
user: config.USERNAME,
password: config.PASSWORD,
database: config.DATABASE,
port: config.PORT,
rowsAsArray: false, // 实际设置为true都是返回数组格式
multipleStatements: false // 实际设置为true都是可以操作多条数据
};
一、createConnection
使用
- 定义
import mysql, { Connection, ConnectionOptions, ResultSetHeader, RowDataPacket} from 'mysql2/promise';
export class MySQLConnection {
// 连接
private conn: Connection | null;
// 连接选项
private credentials: ConnectionOptions;
constructor(credentials: ConnectionOptions) {
this.credentials = credentials;
this.conn = null
mysql.createConnection(this.credentials).then((conn) => {
this.conn = conn
});
}
/** 调用方法前判断断开连接需再次执行链接 */
private async ensureConnection() {
if (!this?.conn) this.conn = await mysql.createConnection(this.credentials);
}
/** 对于`SELECT` and `SHOW`语句,返回对象数据 */
public queryRows = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.query.bind(this.conn)<ResultSetHeader>(sql);
}
/** 对于`SELECT` and `SHOW`语句,返回数组数据(rowsAsArray需设置为true) */
public queryRowsAsArray = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.query.bind(this.conn)<RowDataPacket[][]>(sql);
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作单条) */
public queryResult = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.query.bind(this.conn)<ResultSetHeader>(sql);
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作多条)(multipleStatements需设置为true) */
public queryResults = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.query.bind(this.conn)<ResultSetHeader[]>(sql);
}
/** 对于`SELECT` and `SHOW`语句,返回对象数据 */
public executeRows = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.execute.bind(this.conn)<RowDataPacket[]>(sql);
}
/** 对于`SELECT` and `SHOW`语句,返回数组数据(rowsAsArray需设置为true) */
public executeRowsAsArray = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.execute.bind(this.conn)<RowDataPacket[][]>(sql);
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作单条) */
public executeResult = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.execute.bind(this.conn)<ResultSetHeader>(sql);
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作多条)(multipleStatements需设置为true) */
public executeResults = async (sql: string) => {
await this.ensureConnection();
if(!this.conn) return []
return await this.conn.execute.bind(this.conn)<ResultSetHeader[]>(sql);
}
}
- 使用
import { MySQLConnection } from '../data-base/connection';
const connection = new MySQLConnection(mysqlAccess)
router.post('/login', async(ctx: Koa.Context) => {
const { body } = ctx.request
const { userName, passWord } = body as User
const sql = `select * from user where user_name = '${userName}' and pass_word = '${passWord}'`
const [result] = await connection.executeRowsAsArray(sql);
let resultData = {}
if(result instanceof Array) {
resultData = result[0]
}
ctx.body= {
code:'200',
data: resultData,
msg:'登录成功',
}
})
二、createPool
- 定义
import { Pool, PoolOptions, ResultSetHeader, RowDataPacket, createPool } from 'mysql2/promise';
export class MySQLPool {
// 连接池
private conn: Pool;
// 连接池选项
private credentials: PoolOptions;
constructor(credentials: PoolOptions) {
this.credentials = credentials;
this.conn = createPool(this.credentials);
}
/** 调用方法前判断断开连接需再次执行链接 */
private ensureConnection() {
if (!this?.conn) this.conn = createPool(this.credentials);
}
/** 对于`SELECT` and `SHOW`语句,返回对象数据 */
get queryRows() {
this.ensureConnection();
return this.conn.query.bind(this.conn)<RowDataPacket[]>;
}
/** 对于`SELECT` and `SHOW`语句,返回数组数据 */
get queryRowsAsArray() {
this.ensureConnection();
return this.conn.query.bind(this.conn)<RowDataPacket[][]>;
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作单条) */
get queryResult() {
this.ensureConnection();
return this.conn.query.bind(this.conn)<ResultSetHeader>
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作多条)(multipleStatements需设置为true) */
get queryResults() {
this.ensureConnection();
return this.conn.execute.bind(this.conn)<ResultSetHeader[]>
}
/** 对于`SELECT` and `SHOW`语句,返回对象数据 */
get executeRows() {
this.ensureConnection();
return this.conn.execute.bind(this.conn)<RowDataPacket[]>;
}
/** 对于`SELECT` and `SHOW`语句,返回数组数据 */
get executeRowsAsArray() {
this.ensureConnection();
return this.conn.execute.bind(this.conn)<RowDataPacket[][]>;
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作单条) */
get executeResult() {
this.ensureConnection();
return this.conn.execute.bind(this.conn)<ResultSetHeader>
}
/** 对于`INSERT`, `UPDATE`等更改数据的语句(操作多条)(multipleStatements需设置为true) */
get executeResults() {
this.ensureConnection();
return this.conn.execute.bind(this.conn)<ResultSetHeader[]>
}
}
- 使用
import { MySQLPool } from '../data-base/pool';
const pool = new MySQLPool(mysqlAccess);
router.post('/login2', async(ctx: Koa.Context) => {
const { body } = ctx.request
const { userName, passWord } = body as User
const sql = `select * from user where user_name = '${userName}' and pass_word = '${passWord}'`
const [result] = await pool.queryRows(sql);
let resultData = {}
if(result instanceof Array) {
resultData = result[0]
}
ctx.body= {
code:'200',
data: resultData,
msg:'登录成功',
}
})