1.新建基础架构
①创建项目文件名,
mkdir ‘名称’ ->cd ‘文件名’ -> mkdir ‘src’->npm init
mkdir 'fileName'
cd 'fileName'
mkdir 'src'
npm init
在当前项目名目录下执行npm init,按照默认执行就会创建package.json.
之后执行 npm i @jest/globals @casl/ability bcrypt env-cmd jest mssql reflect-metadata ts-jest ts-node typeorm typeorm-naming-strategies
②创建配置文件tsconfig.json
执行 npx tsc --init
这里会生成默认的配置信息
下面这里是我的配置项:
{
“compilerOptions”: {
“lib”: [
“es5”,
“es6”
],
“target”: “es2017”,
“module”: “commonjs”,
“moduleResolution”: “node”,
“outDir”: “./lib”,
“rootDir”: “./src”,
“emitDecoratorMetadata”: true,
“experimentalDecorators”: true,
“allowSyntheticDefaultImports”: true,
“skipLibCheck”: true,
“sourceMap”: true,
“declaration”: true
},
“include”: [“src”],
“exclude”:[“node_modules”,“lib”]
}
③手动生成ormconfig.js和jest.config.js
New-Item -Path . -Name "jest.config.js" -ItemType "File"
New-Item -Path . -Name "ormconfig.js" -ItemType "File"
下面是执行后生成的目录和信息
执行
修改里面文件的内容
jest.config.js
添加
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ module.exports = { preset: 'ts-jest', testEnvironment: 'node', };
ormconfig.js
添加
const SnakeNamingStrategy =require("typeorm-naming-strategies").SnakeNamingStrategy;
class CustomNamingStrategy extends SnakeNamingStrategy {primaryKeyName(tableOrName, columnNames) {let table = tableOrName instanceof Object ? tableOrName.name : tableOrName;let columnsSnakeCase = columnNames.join("_");return `PK_${table}_${columnsSnakeCase}`.toUpperCase();}
}module.exports = {type: process.env.DB_TYPE,host: process.env.DB_HOST,port: parseInt(process.env.DB_PORT),username: process.env.DB_USERNAME,password: process.env.DB_PASSWORD,database: process.env.DB_SCHEMA,synchronize: false,entities: ["src/entity/**/*.ts"],migrations: ["src/migration/**/*.ts"],subscribers: ["src/subscriber/**/*.ts"],cli: {entitiesDir: "src/entity",migrationsDir: "src/migration",subscribersDir: "src/subscriber",},options: {trustServerCertificate: true,cryptoCredentialsDetails: {minVersion: 'TLSv1'}},namingStrategy: new CustomNamingStrategy(),
};
④创建.env.development配置文件
New-Item -Path . -Name ".evn.development" -ItemType "File"
添加内容:
NODE_ENV=production
#Database Settings
DB_TYPE=your-db-type
DB_HOST=your-db-address
DB_PORT=your-db-port
DB_USERNAME=your-db-name
DB_PASSWORD=your-db-password
DB_SCHEMA=your-connect-db-name#Password Hashing
SALT_ROUNDS=8
⑤创建忽略文件.gitignore
New-Item -Path . -Name ".gitignore" -ItemType "File"
添加内容:
.idea/ .vscode/ node_modules/ build/ tmp/ temp/
2.在src下创建entity文件夹,用于作为迁移内容
我这里用两个文件来说明:user和userRole来处理
①user.entity.ts
import {Entity,PrimaryGeneratedColumn,Column,CreateDateColumn,DeleteDateColumn,UpdateDateColumn,ManyToOne,JoinColumn,Unique,
} from "typeorm";
import { UserRole } from "./user-role.entity";@Unique("UQ_NAME", ["name"])
@Unique("UQ_EMAIL", ["email"])
@Entity("users")
export class User {static readonly modelName = "User";@PrimaryGeneratedColumn()id: number;@Column({ type: "varchar", length: 255 })name: string;@ManyToOne(() => UserRole, (userRole) => userRole.users, { eager: true })@JoinColumn()userRole: UserRole | undefined;@Column()userRoleId: number;@Column({ type: "tinyint", default: 0 })type: number;@Column({ type: "tinyint", default: 0 })branch: number;@Column({ type: "varchar", length: "255", select: false }) // Select false prevent password showing up in repository apipassword: string;@Column({ type: "varchar", length: "255" })email: string;@Column({ type: "varchar", length: 255 })token: string;@Column({ type: "tinyint", default: 0 })status: number;@CreateDateColumn()createdAt: Date;@UpdateDateColumn()updatedAt: Date;@DeleteDateColumn({ nullable: true })deletedAt: Date;@Column({ type: "tinyint", default: 0 })userLock:number;
}
②user-role.ts
import {Entity,PrimaryGeneratedColumn,Column,CreateDateColumn,DeleteDateColumn,UpdateDateColumn,OneToMany,
} from "typeorm";
import { User } from "./user.entity";@Entity("user_roles")
export class UserRole {static readonly modelName = "UserRole";@PrimaryGeneratedColumn()id: number;@Column({type: "nvarchar",length: 255,})name: string;@Column({ type: "tinyint", default: 0 })status: number;@CreateDateColumn()createdAt: Date;@UpdateDateColumn()updatedAt: Date;@DeleteDateColumn()deletedAt: Date;//Relations@OneToMany(() => User, (user) => user.userRole, { cascade: true })users: User[] | undefined;
}
③在src下创建index.ts中导出这两个内容
export { User } from "./entity/user.entity"; export { UserRole } from "./entity/user-role.entity";
**
3.执行命令查看生成内容
①执行:npm i
②执行:env-cmd -f .env.development npm run typeorm migration:generate – -p -n YourMigrationName,
这里会生成执行可以执行的sql文件,并且会在migration中
③执行:env-cmd -f .env.development npm run typeorm migration:run – -t=false
这里会将表生成到db中
这时候基本就大体可以用了.
4.生成种子
这里的种子就是给数据库添加基础的数据
①在src下创建seed文件夹
创建
user-user-role.seed.ts文件
import { Seeder, Factory } from 'typeorm-seeding';
import { Connection } from 'typeorm';
import { User } from "../entity/user.entity";
import { UserRole } from "../entity/user-role.entity";
import { Action } from "../casl/action.enum";
import { hash } from "bcrypt";export const UserSeed = {name: "Admin",password: "初始化的密码",email: "你自己提供的邮箱",token: "token",status: 1,
};export const UserRoleSeed = {name: "Administrator",status: 1,
};export default class UserUserRoleSeed implements Seeder {public async run(factory: Factory, connection: Connection): Promise<void> {try {const userRepository = connection.getRepository<User>("users");const userRoleRepository = connection.getRepository<UserRole>("user_roles");//init clean user and user role tablesconst userData = await connection.getRepository("users").query(`DELETE FROM [users];`);const userRoleData = await connection.getRepository("user_roles").query(`DELETE FROM [user_roles];`);const userRoleSeed = userRoleRepository.create(UserRoleSeed);const userSeed = userRepository.create(UserSeed);userSeed.password = await hash(userSeed.password, +process.env.SALT_ROUNDS);userRoleSeed.users = [userSeed];const userRole = await connection.getRepository("user_roles").save(userRoleSeed);console.log('User role seeding completed successfully');} catch (error) {console.error('Error during seeding:', error);}}
}
②.在src下创建run-seed.ts文件
import 'reflect-metadata';
import { createConnection, getConnectionOptions } from 'typeorm';
import { Seeder, factory } from 'typeorm-seeding';
import UserUserRoleSeed from './seed/user-user-role.seed';
//import AnotherSeed from './seed/AnotherSeed'; // 导入其他 Seederasync function runSeeder() {try {const connectionOptions = await getConnectionOptions();const connection = await createConnection(connectionOptions);// 创建一个 Seeder 实例并运行//const seeders: Seeder[] = [new UserUserRoleSeed(), new AnotherSeeder()];const seeders: Seeder[] = [new UserUserRoleSeed()];for (const seeder of seeders) {await seeder.run(factory, connection);}await connection.close();console.log('Seeding complete.');} catch (error) {console.error('Error running seeder:', error);}
}runSeeder();
这里就是用来执行初始化代码的内容
在package.json的scripts下添加一条执行命令:
"seed:run": "env-cmd -f .env.development ts-node src/run-seed.ts"
添加好之后,点击调试在命令窗口会出现
npm run seed:run
这条命令,可以查看到数据库生成了初始的数据了.