存储数据
服务端应用需要一种方法跟数据仓库连接,然后就可以处理这个数据仓库里的数据了,比如用户可以通过应用的客户端去发布一个内容,这个内容会通过网络交给服务端应用,服务端收到请求会把这个请求主题里面的数据提取出来,然后把它放在应用的数据仓库里存储起来,这样以后需要用到这个数据的时候就可以从数据仓库里调取出来。
数据连接
通常会使用一种叫做 Drivers 的东西,字面意思是数据驱动,驱动就知道它怎么跟服务端应用沟通,也知道怎么去连接某一种类型的数据仓库服务,有点像中间人,负责把服务端应用要做的事情告诉给数据仓库服务。找一个适用于后台语言并能够连接到使用的数据仓库服务的驱动。在 node 里面,这种驱动就是一个包,比如 mysql、mysql2。
安装驱动连接数据仓库
使用 mysql2 这个包提供的功能去连接使用 mysql 类型的数据仓库服务
如果使用了 typescript,还需要安装一下这个包的类型定义,这样编辑器就知道 mysql2 这个包里都有什么东西了
1
| npm install types/mysql2 --save-dev
|
使用 mysql2 连接
在应用里可以新建一个连接,然后可以去重复使用这个连接,在这个连接里面需要设置连接的那个数据仓库服务的主机、端口号、用户、还有密码之类的信息,这些信息可以保存在项目的环境变量里面,比如
设置环境变量
1 2 3 4 5 6
| #数据仓库配置 MYSQL_HOST=localhost MYSQL_POST=3306 MYSQL_USER=root MYSQL_PASSWORD=cxn931119 MYSQL_DATABASE=xb2_node
|
在 config.js 中导出
1 2 3 4 5 6 7 8 9 10
| /** * 数据仓库配置 */ export const { MYSQL_HOST, MYSQL_POST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE } = process.env;
|
创建一个数据服务连接,新建文件 database/mysql.ts,创建连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import mysql from 'mysql2'; import{ MYSQL_HOST, MYSQL_POST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE } from '../../app/app.config';
/** * 创建数据服务连接 */ export const connection = mysql.createConnection({ host:MYSQL_HOST, port:parseInt(MYSQL_POST,10), user:MYSQL_USER, password:MYSQL_PASSWORD, database:MYSQL_DATABASE })
|
测试一下,在 main.ts 中输入后在终端中使用 node 运行一下,控制台打印成功连接服务。
1 2 3 4 5 6 7 8 9 10 11 12
| import {connection} from './app/database/mysql'
/** * 测试试用数据服务连接 */ connection.connect(error=>{ if(error){ console.log('连接数据服务失败',error.message); return } console.log('成功连接服务') })
|
调取内容
post.service.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import {connection} from '../app/database/mysql'
/** * 获取内容列表 */ export const getPosts = async () => { const statement = ` SELECT * FROM post `; const [data] = await connection.promise().query(statement);
return data; };
|
post.controller.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { Request, Response, NextFunction } from 'express'; //引入接口、处理器、参数需要的类型 import { getPosts } from './post.service';
/** * 内容列表 */ export const index = async ( request: Request, response: Response, next: NextFunction, ) => { const posts = await getPosts(); response.send(posts); };
|
利用数据之间的关系
post.service.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import {connection} from '../app/database/mysql' /** * 获取内容列表 */ export const getPosts = async () => { const statement = ` SELECT post.id, post.title, post.content, JSON_OBJECT( //使用JSON_OBJECT创建了一个存放作者信息的对象 'id', user.id, 'name', user.name ) as user FROM post LEFT JOIN user ON user.id = post.userId `; const [data] = await connection.promise().query(statement);
return data; };
|
处理使用数据服务时遇到的异常情况
在控制器中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { Request, Response, NextFunction } from 'express'; //引入接口、处理器、参数需要的类型 import { getPosts } from './post.service';
/** * 内容列表 */ export const index = async ( request: Request, response: Response, next: NextFunction, ) => { try { const posts = await getPosts(); response.send(posts); } catch (error) { next(error) //将error交给默认的异常处理器 } };
|
在中间件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| /** * 默认异常处理器 */ export const defaultErrorHandler = ( error: any, request: Request, response: Response, next: NextFunction, ) => { if(error.message){ console.log(error.message) //如果有error.message,在控制台上打印 } let statusCode: number, message: string;
/** * 处理异常 */ switch (error.message) { default: statusCode = 500; message = '服务暂时出了点问题~'; break; } response.status(statusCode).send({ message }); };
|