express项目使用mysql2

1656 字
8 分钟
express项目使用mysql2

之前使用#

封装接口调用函数#

之前使用后端提供的接口进行数据库的增删改查:

import request from '@lib/request.js'
/** 查询 */
export const selectDB = (body, headers) => {
return request.post(`/db/${body.database}/select`, body, {
headers: { token: headers.token },
})
}
/** 修改 */
export const updateDB = (body, headers) => {}
/** 新增 */
export const insertDB = (body, headers) => {}

使用#

const _body = {
database: database.qmp_data_sso.name,
table: database.qmp_data_sso.table.qmp_user_info,
column: [],
where: {
wheres: [{ column: 'display_flag', opt: '=', value: '1' }],
},
}
return db.selectDB(_body, headers)

mysql vs mysql2#

mysql 实现 MySQL 协议的纯 Node.js JavaScript 客户端

mysql2 ⚡ 适用于 Node.js 的快速 mysqljs/mysql 兼容 mysql 驱动程序

MySQL2 的历史以及选择原因

mysql2 是 mysql 包的升级版,有更多特性。

express 使用 mysql2 基础配置#

1. 安装依赖#

Terminal window
yarn add mysql2

配置数据库连接池#

可以通过 createConnection 在需要操作数据库的时候,建立连接,用完之后释放连接,但这样会浪费性能,因为数据库的连接建立还是很耗时的,而且一个连接也不够用。

这时候就需要连接池来管理数据库连接、提高 mysql 的使用性能并减少资源消耗:连接池会重用以前的连接而不是重新创建连接,保持打开而不是关闭。

mysql-pool
mysql-pool

连接池中放着好几个 mysql 的连接对象,用的时候取出来执行 sql,用完之后放回去,不需要断开连接。

创建一个数据库连接池并导出,以便在整个应用程序中共享使用:

import {
MYSQL_HOST,
MYSQL_PORT,
MYSQL_USER,
MYSQL_PASSWORD,
} from '../../index.js'
import mysql from 'mysql2/promise'
const pool = mysql.createPool({
host: MYSQL_HOST,
port: MYSQL_PORT,
user: MYSQL_USER,
password: MYSQL_PASSWORD,
database: 'passport',
waitForConnections: true, //连接超额是否等待
connectionLimit: 10, //一次创建的最大连接数
queueLimit: 0, //可以等待的连接的个数
maxIdle: 10, // 超过10个空闲会释放
idleTimeout: 60000, // 空闲的连接需要多久断开
enableKeepAlive: true,
keepAliveInitialDelay: 0,
})
export default pool

数据库连接相关配置写在 config 中

连接池配置:

  • connectionLimit:指定连接池中允许的最大连接数,比如 10,也就是同时最多使用 10 个,再多就需要排队
  • queueLimit:指定当连接池中的连接已满时,请求排队等待的最大数量,设置为 0 时没有上限
  • waitForConnections:指定是否等待可用连接。如果设置为 true,则在连接不足时请求将被排队,为 false 时直接报错
  • maxIdle:指定最多有多少个空闲的,超过这个数量的空闲连接会被释放
  • idleTimeout:空闲的连接需要多久断开
  • enableKeepAlive、keepAliveInitialDelay:保持心跳用的,默认值即可

3. 使用连接池执行数据库操作#

在模型层(model 层),使用连接池的 getConnection 方法获取连接,执行数据库操作需要释放连接,详见官方文档

// 实现一个查询用户数量的接口
import pool from '@/config/database.js'
const UserCountModel = {
async getAllUserCount() {
let connection
try {
connection = await pool.getConnection()
const [rows, filed] = await connection.query(
'SELECT count(*) FROM user_info'
)
return rows
} catch (error) {
throw error
} finally {
if (connection) connection.release() // 释放连接回连接池
}
},
}

query 返回结果

  • rows:数组,包含了查询结果的所有行数据。每一行数据通常是一个对象,具体结构取决于查询语句的结果。如果没有匹配的行,则 rows 是一个空数组 []。
  • fields:数组,包含了查询结果的字段信息。每个字段对象通常包含字段的名称、类型等信息。如果查询结果不包含字段(例如 SELECT COUNT(*)),则 fields 是 undefined。

express-mysql2-count
express-mysql2-count

注意事项

  • 错误处理:务必在适当的地方捕获和处理数据库操作可能出现的错误,例如网络中断、SQL 错误等。

  • 连接释放:使用 connection.release() 方法来释放连接回连接池,以便其他请求可以继续使用。

4. 在 Controller 层调用 Model 层的方法#

import UserCountModel from '@/models/userCountModel.js'
// 获取所有用户数量
export const getAllUserCount = async (req, res) => {
try {
const users = await UserCountModel.getAllUserCount()
res.json(users)
} catch (err) {
res.status(500).json({ message: err.message })
}
}

5. 通过路由调用 Controller 层#

import express from 'express'
import { getAllUserCount } from '@/controllers/userCountCountController.js'
const router = express.Router()
// GET /count 路由
router.get('/count', getAllUserCount)
export default router

报错集锦#

node_modules/mysql2/node_modules/lru-cache/dist/cjs/index.js:781 this.#dispose?.(oldVal, k, ‘set’);#

太坑了,必须把 mysql2 版本降到 3.0.0,不然报错

解决方法

TypeORM#

使用上述方法可以正常的在 node 中操作数据库,但一般不会这样直接执行 sql,而是会使用 ORM 框架。

ORM 是 Object Relational Mapping(对象关系映射)。就是把 mysql 这种关系型数据库的表映射成面向对象的 Class,表的字段映射成对象的属性映射,表与表的关联映射成属性的关联。

TypeORM 就是用于 TypeScript 和 JavaScript 流行的 ORM 框架,兼容多种数据库。

TypeORM 特性

  • 实体 (Entity):定义数据库表的类。
  • 仓库 (Repository):用于访问实体的存储库。
  • 迁移 (Migration):管理数据库迁移。
  • 查询生成器 (Query Builder):以编程方式构建 SQL 查询。
  • 数据映射和关系:支持一对一、一对多、多对多等关系。

使用步骤#

1. 安装依赖#

Terminal window
npm install typeorm reflect-metadata

需要在应用程序的全局位置导入(例如在 app.ts 中)

Terminal window
import 'reflect-metadata'

2. TypeORM 配置#

ormconfig.json 是 TypeORM 的配置文件,用于配置数据库连接、实体、迁移等信息。

在项目根目录创建一个 ormconfig.json 文件,配置数据库连接:

{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "password",
"database": "test",
"synchronize": true,
"logging": false,
"entities": ["src/entity/**/*.ts"],
"migrations": ["src/migration/**/*.ts"],
"subscribers": ["src/subscriber/**/*.ts"]
}
  • synchronize: 同步建表,也就是当 database 里没有和 Entity 对应的表的时候,会自动生成建表 sql 语句并执行。
  • logging: 打印生成的 sql 语句
  • entities: 是指定有哪些和数据库的表对应的 Entity

TypeORM 会自动读取项目根目录中的 ormconfig.json 文件来配置连接和其他设置。在代码中无需显式引用 ormconfig.json,TypeORM 会自动读取和使用该文件的配置。

3. 创建数据库连接模块#

在 src/config 目录中创建一个 datasource.js 文件,用于管理数据库连接:

import 'reflect-metadata'
import { createConnection } from 'typeorm'
const connectDatabase = async () => {
try {
await createConnection()
console.log('数据库链接建立成功')
} catch (error) {
console.error('连接数据库失败', error)
throw error
}
}
export default connectDatabase

4. 创建实体 Entity#

实体 (Entity) 是 TypeORM 映射到数据库表的类。每个实体类代表数据库中的一张表,类中的每个属性对应表中的一列。

如我们数据库有一个 user_info 表:

typeorm-user-info
typeorm-user-info

user_info 表具有以下列:

  • id (主键)
  • uuid (字符串)
  • nickname
  • avatar
  • desc
  • phone
  • created_at (日期时间)
  • updated_at
  • deleted_at
  • display_flag

我们创建一个对应的实体类 src/entity/UserInfo.js

express项目使用mysql2
https://wangxiang.website/posts/前端工程/express-mysql2/
作者
翔子
发布于
2024-06-22
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
翔子
前端开发工程师
公告
博客已从 VitePress 迁移到 Astro + Firefly 主题,223 篇文章全部保留。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
221
分类
9
标签
28
总字数
411,914
运行时长
0
最后活动
0 天前

文章目录