主题:使用 TypeORM 访问 MariaDB 数据库
环境准备
说明:本文使用 MySQL 的示例数据库 world 作为演示数据。使用 MariaDB 自带的客户端 HeidiSQL 执行 world.sql 脚本时会出错,可以使用 MySQL 的客户端工具 MySQL Workbench,或者使用 MySQL 数据库。
安装 TypeORM
打开命令提示符窗口,输入 npm install typeorm -g
并回车。安装结果如下图:
此时输入 typeorm --version
可查看安装的 TypeORM 的版本号。本示例安装的 TypeORM 的版本是 0.2.7。
创建项目文件夹
在 D: 盘新建 typeorm-example 文件夹。
项目初始化
启动 Visual Studio Code,点击菜单 [文件] -> [打开文件夹],选择刚才创建的 D:\typeorm-example
文件夹。
点击菜单 [查看] -> [集成终端],打开终端窗口。点击终端窗口工具栏前的下拉框,切换到 cmd
模式。
在命令提示符后面输入 typeorm init --database mariadb --express
并回车,执行结果如下图:
生成的项目结构如下图:
打开 README.md
文件,执行其中的第 1 步和第 2 步:
1、在命令提示符后输入 npm i
并回车,安装相关的依赖包。
2、打开 ormconfig.json
文件,修改其中的数据库选项。注意修改 database
为 world
,修改 synchronize
为 false
。
"type": "mariadb",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "xxxx",
"database": "world",
"synchronize": false,
创建数据模型
在 entity
文件夹上点击鼠标右键,在弹出菜单上选择<新建文件>,输入文件名 country.ts
并回车。
新建的 country.ts 文件会自动打开,编辑文件内容如下:
import {Entity, PrimaryColumn, Column} from "typeorm";
@Entity("country")
export class Country {
@PrimaryColumn({name: "Code"})
code: string;
@Column({name:"Name"})
name: string;
@Column({name:"Continent"})
continent: string;
@Column({name:"SurfaceArea"})
surfaceArea: string;
@Column({name:"IndepYear"})
indepYear: string;
@Column({name:"Population"})
population: string;
}
创建控制器
在 controller
文件夹上点击鼠标右键,在弹出菜单上选择<新建文件>,输入文件名 countryController.ts
并回车。
新建的 countryController.ts 文件会自动打开,编辑文件内容如下:
import {getRepository} from "typeorm";
import {NextFunction, Request, Response} from "express";
import {Country} from "../entity/country";
export class CountryController {
private countryRepository = getRepository(Country);
async one(request: Request, response: Response, next: NextFunction) {
const country = await this.countryRepository.findOne(request.params.id);
return country;
}
async all(request: Request, response: Response, next: NextFunction) {
const countries = await this.countryRepository.find();
return countries;
}
}
添加路由
打开 routes.ts
文件,在最后添加如下代码:
{
method: "get",
route: "/country",
controller: CountryController,
action: "all"
}, {
method: "get",
route: "/country/:id",
controller: CountryController,
action: "one"
}
去掉无用的代码
默认生成的代码里,项目启动时会自动创建 User 表,并向表中插入两条记录。
打开 index.ts
文件,注释掉或删除如下代码:
// insert new users for test
await connection.manager.save(connection.manager.create(User, {
firstName: "Timber",
lastName: "Saw",
age: 27
}));
await connection.manager.save(connection.manager.create(User, {
firstName: "Phantom",
lastName: "Assassin",
age: 24
}));
这个版本的 TypeORM 去掉了 Repository 对象的 removeById 函数,而示例代码里仍然使用了这个函数,这会导致编译出错。
打开 UserController.ts
文件,注释掉或删除如下代码:
async remove(request: Request, response: Response, next: NextFunction) {
await this.userRepository.removeById(request.params.id);
}
完成后的项目结构
最终项目结构如下图:
运行程序
在终端窗口命令提示符后输入 npm start
并回车,运行程序。出现如下信息,说明运行成功:
打开浏览器,在地址栏输入 http://localhost:3000/country
查看结果,如下图:
在地址栏输入 http://localhost:3000/country/usa
结果如下图:
至此已经完成了 TypeORM 的功能演示,不过对于一个 Web 程序来说,没有一个展示页面是不完整的。
创建演示页面
在 VSCode 资源管理器空白处点击鼠标右键,在弹出菜单上选择<新建文件夹>,输入文件夹名 public
并回车。
在 public
文件夹上点击鼠标右键,在弹出菜单上选择<新建文件>,输入文件名 index.html
并回车。
新建的 index.html 文件会自动打开,编辑文件内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>国家</title>
<style type="text/css">
#countryList {
margin: 30px;
}
.list-row div {
display: inline-block;
}
.col-width-100 {
width: 100px;
}
.col-width-200 {
width: 200px;
}
</style>
</head>
<body>
<div id="countryList">
<div class="list-row">
<div class="col-width-100">代码</div>
<div class="col-width-200">名称</div>
<div class="col-width-100">面积</div>
<div class="col-width-100">人口</div>
<div class="col-width-200">洲</div>
<div class="col-width-100">独立年份</div>
</div>
</div>
<script id="rowTemplate" type="text/template">
<div class="list-row">
<div class="col-code col-width-100"></div>
<div class="col-name col-width-200"></div>
<div class="col-surface-area col-width-100"></div>
<div class="col-population col-width-100"></div>
<div class="col-continent col-width-200"></div>
<div class="col-indep-year col-width-100"></div>
</div>
</script>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.get("country", function(data){
showList(data);
});
});
function showList(data) {
var rowTemplate = $("#rowTemplate").html();
var $rowTemplate = $("<code></code>").append(rowTemplate);
data.forEach(country => {
$(".col-code", $rowTemplate).text(country.code);
$(".col-name", $rowTemplate).text(country.name);
$(".col-surface-area", $rowTemplate).text(country.surfaceArea);
$(".col-population", $rowTemplate).text(country.population);
$(".col-continent", $rowTemplate).text(country.continent);
$(".col-indep-year", $rowTemplate).text(country.indepYear);
$("#countryList").append($rowTemplate.html());
});
}
</script>
</body>
</html>
添加静态资源
上面创建的 public 文件夹及 index.html 文件现在还无法访问,必须作为静态资源添加到项目里才能正常访问。
打开 index.ts
文件,把下面两行代码添加到适当位置:
import * as path from "path";
...
app.use(express.static(path.resolve(__dirname, '../public')));
最终的项目结构
重新运行程序
在终端窗口命令提示符后输入 npm start
并回车,运行程序。
如果程序正在运行,可按
Ctrl+C
结束运行。
打开浏览器,在地址栏输入 http://localhost:3000/index.html
查看结果,如下图: