From 64ab40e566e7e53a8da6fbb877a8de7598e46958 Mon Sep 17 00:00:00 2001 From: tone <3341154833@qq.com> Date: Wed, 25 Sep 2024 02:02:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20MysqlConnection=E3=80=81Re?= =?UTF-8?q?disConnection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + src/config.ts | 11 ++++ src/index.ts | 8 ++- src/lib/Database/MySQLConnection.ts | 84 +++++++++++++++++++++++++++++ src/lib/Database/RedisConnection.ts | 43 +++++++++++++++ 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/lib/Database/MySQLConnection.ts create mode 100644 src/lib/Database/RedisConnection.ts diff --git a/package.json b/package.json index 816c05b..5e59f23 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "@types/node": "^22.6.1", "cors": "^2.8.5", "express": "^4.21.0", + "ioredis": "^5.4.1", + "mysql2": "^3.11.3", "typescript": "^5.6.2" }, "devDependencies": { diff --git a/src/config.ts b/src/config.ts index 5785a4c..0a8c558 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,6 +4,17 @@ const config = { allowedHeaders: ['Content-Type'], methods: ['GET', 'POST'] }, + mysql: { + host: 'localhost', + database: '', + user: 'root', + password: '' + }, + redis: { + host: 'localhost', + port: 6379, + password: '' // localhost + }, API_Port: 8080 }; export default config; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index f28433f..58c1998 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,18 @@ import { APILoader } from "@lib/API/APILoader"; import Logger from '@lib/Logger/Logger' import config from "./config"; +import MySQLConnection from "@lib/Database/MySQLConnection"; +import RedisConnection from "@lib/Database/RedisConnection"; +MySQLConnection +RedisConnection +// import API import GetTest from "./api/GetTest"; const logger = new Logger('Server') + async function main(): Promise { logger.info('Starting...'); const apiLoader = new APILoader(config.cors); - // loadAPI + // addAPI apiLoader.add(GetTest); await apiLoader.start(config.API_Port); diff --git a/src/lib/Database/MySQLConnection.ts b/src/lib/Database/MySQLConnection.ts new file mode 100644 index 0000000..b8af0e9 --- /dev/null +++ b/src/lib/Database/MySQLConnection.ts @@ -0,0 +1,84 @@ +/** + * @file MySQLConnection.ts + * @version 1.0.0 + * @description MySQL数据库连接池 + */ +import mysql from "mysql2/promise"; +import Logger from "@lib/Logger/Logger"; +import config from "../../config"; + +class MySQLConnectPool { + private pool: any; + private logger = new Logger('MySQLConnection'); + + constructor() { + this.pool = this.createConnectPool(); + this.logger.info("Database connection pool created") + setTimeout(async () => { + let res = await this.testConnection(); + if (res) + this.logger.info("Database test successful") + else + this.logger.error("Database test failed") + }, 10); + } + + private createConnectPool() { + return mysql.createPool({ + host: config.mysql.host, + database: config.mysql.database, + user: config.mysql.user, + password: config.mysql.password, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0 + }) + } + + private async testConnection() { + try { + let res = await this.execute("SELECT 1 + 1 As result"); + if (res[0].result == 2) + return 1; + else + return 0; + } catch (error) { + this.logger.error(`An error occurred during the database test: ` + error); + return 0; + } + + } + + /** + * 执行SQL查询 + * @param sql SQL语句 + * @param values 可选的查询参数列表 + * @param database 可选的数据库 + * @returns Promise 查询结果 + */ + public async execute(sql: string, values?: any[], database?: string): Promise { + let connection: any; + try { + connection = await this.pool.getConnection(); + + // 如果指定了数据库,则更改当前连接的数据库 + if (database) { + await connection.changeUser({ database }); + } + + let [rows, fields] = await connection.execute(sql, values); + return rows; + } catch (error) { + this.logger.error("An error occurred in the database: " + error, '\n##', sql, '\n##', JSON.stringify(values)); + return undefined; + } finally { + if (database) + await connection.changeUser({ database: config.mysql.database });// 恢复默认数据库 + if (connection) + connection.release(); + } + } +} + +const MySQLConnection = new MySQLConnectPool(); +export default MySQLConnection; \ No newline at end of file diff --git a/src/lib/Database/RedisConnection.ts b/src/lib/Database/RedisConnection.ts new file mode 100644 index 0000000..0d4e62b --- /dev/null +++ b/src/lib/Database/RedisConnection.ts @@ -0,0 +1,43 @@ +import Redis from 'ioredis'; +import config from '../../config'; +import Logger from '@lib/Logger/Logger'; + +class RedisConnection { + private pool?: Redis + private logger = new Logger('Redis') + + constructor() { + try { + this.pool = new Redis({ + port: config.redis.port, + host: config.redis.host, + password: config.redis.password, + maxRetriesPerRequest: 10, + }); + this.logger.info('Database connection pool created') + } catch (error) { + this.logger.error('Failed to create database connection pool: ' + error) + } + setTimeout(async () => { + if (this.pool == undefined) + return; + try { + let res = await this.pool.set('redis_test', '1'); + if (res) + this.logger.info('Database test successful') + else + throw new Error('Unexpected return value') + } catch (error) { + this.logger.error('Database test failed: ' + error) + } + + }, 10); + } + + public getPool(): Redis { + return this.pool; + } +} + +const redisConnection = new RedisConnection(); +export default redisConnection.getPool(); \ No newline at end of file