[Node.js]Midway使用教程简易版

Midway是阿里提供的渐进式设计,提供从基础到入门再到企业级的升级方案,解决应用维护与拓展性难题

首先你需要有最新的node版本环境

使用命令行

npm init midway

根据提示即可创建完一个项目(演示为Koa为基础)

在项目中我们可以使用安装 typeorm 组件,提供数据库 ORM 能力,还需要安装数据库驱动

npm i @midwayjs/typeorm@3 typeorm --save

# for MySQL or MariaDB,Mysql8使用第二行命令
npm install mysql --save
npm install mysql2 --save

配置数据库链接

src\config\config.default.ts

import { MidwayConfig } from "@midwayjs/core";
//引入实体Model模型
如果不知道可以向下继续看
import { Photo } from "../entity/User";

export default {
  // use for cookie sign key, should change to your own and keep security
  keys: "1678859147957_8252",
  koa: {
    port: 7001
  },
  typeorm: {
    dataSource: {
      default: {
        type: "mysql",
        host: "118.123.238.110",
        port: 3306,
        username: "test1",
        password: "test1",
        database: "test1",
        synchronize: true,
        logging: true,
        //配置实体模型
        entities: [Photo],
        // 或者扫描形式,自动配置实体模型
        entities: [
          '**/entity/*.entity{.ts,.js}'
        ]
      }
    }
  }
} as MidwayConfig;

1、创建 Model

我们通过模型和数据库关联,在应用中的模型就是数据库表,在 TypeORM 中,模型是和实体绑定的,每一个实体(Entity) 文件,即是 Model,也是实体(Entity)。

在示例中,需要一个实体,我们这里拿 photo 举例。新建 entity 目录,在其中添加实体文件 photo.entity.ts ,一个简单的实体如下。

// entity/photo.entity.ts
export class Photo {
id: number;
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}

要注意,这里的实体文件的每一个属性,其实是和数据库表一一对应的,基于现有的数据库表,我们往上添加内容。

2、定义实体模型

我们使用 Entity 来定义一个实体模型类。

// entity/photo.entity.ts
import { Entity } from 'typeorm';

@Entity('photo')
export class Photo {
id: number;
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}

如果表名和当前的实体名不同,可以在参数中指定。

// entity/photo.entity.ts
import { Entity } from 'typeorm';

@Entity('photo_table_name')
export class Photo {
id: number;
name: string;
description: string;
filename: string;
views: number;
isPublished: boolean;
}

这些实体列也可以使用 typeorm_generator 工具生成。

3、添加数据库列

通过 typeorm 提供的 @Column 装饰器来修饰属性,每一个属性对应一个列。

// entity/photo.entity.ts
import { Entity, Column } from 'typeorm';

@Entity()
export class Photo {

@Column()
id: number;

@Column()
name: string;

@Column()
description: string;

@Column()
filename: string;

@Column()
views: number;

@Column()
isPublished: boolean;

}

现在 id , name , description ,filename , views , isPublished 列将添加到 photo 表中。数据库中的列类型是根据您使用的属性类型推断出来的,例如 number 将转换为整数,将字符串转换为 varchar,将布尔值转换为 bool,等等。但是您可以通过在 @Column装饰器中显式指定列类型来使用数据库支持的任何列类型。

我们生成了带有列的数据库表,但是还剩下一件事。每个数据库表必须具有带主键的列。

数据库列包括更多的列选项(ColumnOptions),比如修改列名,指定列类型,列长度等,更多的选项请参考 官方文档

4、创建主键列

每个实体必须至少具有一个主键列。要使列成为主键,您需要使用 @PrimaryColumn 装饰器。

// entity/photo.entity.ts
import { Entity, Column, PrimaryColumn } from 'typeorm';

@Entity()
export class Photo {

@PrimaryColumn()
id: number;

@Column()
name: string;

@Column()
description: string;

@Column()
filename: string;

@Column()
views: number;

@Column()
isPublished: boolean;

}

5、创建自增主键列

现在,如果要设置自增的 id 列,需要将 @PrimaryColumn 装饰器更改为 @PrimaryGeneratedColumn 装饰器:

// entity/photo.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {

@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;

@Column()
description: string;

@Column()
filename: string;

@Column()
views: number;

@Column()
isPublished: boolean;

}

6、列数据类型

接下来,让我们调整数据类型。默认情况下,字符串映射到类似 varchar(255) 的类型(取决于数据库类型)。 Number 映射为类似整数的类型(取决于数据库类型)。但是我们不希望所有列都限制为 varchars 或整数,这个时候可以做一些修改。

// entity/photo.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {

@PrimaryGeneratedColumn()
id: number;

@Column({
length: 100
})
name: string;

@Column('text')
description: string;

@Column()
filename: string;

@Column("double")
views: number;

@Column()
isPublished: boolean;
}

示例,不同列名

@Column({
length: 100,
name: 'custom_name'
})
name: string;

此外还有有几种特殊的列类型可以使用:

  • @CreateDateColumn 是一个特殊列,自动为实体插入日期。
  • @UpdateDateColumn 是一个特殊列,在每次调用实体管理器或存储库的save时,自动更新实体日期。
  • @VersionColumn 是一个特殊列,在每次调用实体管理器或存储库的save时自动增长实体版本(增量编号)。
  • @DeleteDateColumn 是一个特殊列,会在调用 soft-delete(软删除)时自动设置实体的删除时间。

比如:

  @CreateDateColumn({
type: 'timestamp',
})
createdDate: Date;

列类型是特定于数据库的。您可以设置数据库支持的任何列类型。有关支持的列类型的更多信息,请参见此处

提示

CreateDateColumn 和 UpdateDateColumn 是依靠第一次同步表结构时,创建列上的默认数据完成的插入日期功能,如果是自己创建的表,需要自行在列上加入默认数据。

在controller文件夹下创建控制层书写业务代码

import { Inject, Controller, Post, Body } from "@midwayjs/core";
import { Context } from "@midwayjs/koa";
import { UserService } from "../service/user.service";
import { User } from "../entity/User";


// 数据通过接口传递到控制层
@Controller("/api/user")
export class APIController {
  @Inject()
  ctx: Context;

  @Inject()
  userService: UserService;

  @Post("/create")
  // 从Body中取出express中的body数据
  async create(@Body() user: User): Promise<User> {
    // 对象拷贝
    Object.assign(user, {
      regtime: new Date()
    });
    return this.userService.create(user);
  }
}

来到服务层写我们的方法

import { Provide } from "@midwayjs/core";
import { IUserOptions } from "../interface";
//引入实体类
import { User } from "../entity/User";
import { Repository } from "typeorm";
import { InjectEntityModel } from "@midwayjs/typeorm";

@Provide()
export class UserService {
  @InjectEntityModel(User)
    // 通过实体类创建模型 userModel为模型名称
  userModel: Repository<User>;

  async create(user: User): Promise<User> {
//只需要保存即可将数据保存在数据库中
    return this.userModel.save(user);
  }

  async getUser(options: IUserOptions) {
    return {
      uid: options.uid,
      username: "mockedName",
      phone: "12345678901",
      email: "xxx.xxx@xxx.com"
    };
  }

}

还记得我们在entity中创建的实体类吗

import { Column, Entity, PrimaryColumn } from "typeorm";

// 映射表->实体类
@Entity("user")
export class User {
  @PrimaryColumn({ type: "bigint" })
  id: number;
  @Column({ length: 100, nullable: false, unique: true })
  username: string;
  @Column({ length: 200, nullable: false })
  password: string;
  @Column({ length: 20, nullable: true })
  phoneNum: string;
  @Column()
  regtime: Date;
}

在这里他映射了数据库中的表字段,当第一次运行时,数据库中不存在这些数据,它会自动创建表并配置信息

到此为止一个保存到数据库user表的接口就完成了,只要将在接口中通过传递json的方法把在实体类中设置的规则的参数传递,就可以完成接口的响应了

也许你可能对包装类,包装器这种名词感到陌生晦涩难懂,在下一次的文章中,将会用白话的方式帮助刚接触的朋友轻松理解

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索