typeorm完成简单的CRUD

新增用户

在进行CRUD演示之前,先简单的介绍一下依赖注入:

什么是依赖注入?依赖注入是一种设计模式,它可以帮助我们更好地管理类之间的依赖关系。在依赖注入中,我们不再直接在类中创建依赖项,而是将它们注入到类中。这样做的好处是,它可以使我们的代码更加灵活和可维护。在下方例子中,@InjectRepository(User) 是一个装饰器,它告诉 NestJS 框架需要注入一个名为 UserRepository 的依赖项,这个依赖项的类型是 Repository<User>。这个装饰器是由 NestJS 框架提供的,它可以让我们在类中使用依赖注入功能,从而更好地管理类之间的依赖关系。

less 复制代码
constructor(
  @InjectRepository(User) private UserRepository: Repository<User>,
  ) {}

这段代码是一个构造函数,它接受一个名为 UserRepository 的私有变量,该变量的类型为 Repository<User>。这个构造函数使用了 NestJS 框架的依赖注入功能,它将 UserRepository 注入到了这个类中,以便在这个类的其他方法中使用。@InjectRepository(User) 是一个装饰器,它告诉 NestJS 框架需要注入一个名为 UserRepository 的依赖项,这个依赖项的类型是 Repository<User>。这个装饰器是由 NestJS 框架提供的,它可以让我们在类中使用依赖注入功能,从而更好地管理类之间的依赖关系。¹

在Nest.js中,@InjectRepository(User) private UserRepository: Repository<User> 是使用TypeORM时,依赖注入(Dependency Injection)的一种方式。

@InjectRepository(User): 这是TypeORM提供的一个装饰器,用于告诉Nest.js要注入的依赖是一个数据库实体(Entity),这里是User实体。@InjectRepository装饰器的参数是一个TypeORM实体类,它指定了要注入的实体类型。

private UserRepository: Repository<User>: 这里创建了一个私有成员变量 UserRepository,它的类型是 Repository<User>。Repository 是TypeORM提供的一个通用仓库类,用于执行与数据库实体(例如User)相关的操作,比如保存、查询、删除等。

综合起来,这段代码的作用是将一个Repository实例(即数据库操作的仓库)注入到当前的类中。通过这个UserRepository,你可以在该类的方法中执行各种数据库操作,而无需在每个方法中都显式地创建新的仓库实例

这种写法是 TypeScript 中的构造函数语法。在这个例子中,构造函数是一个空函数,它没有任何参数。但是,如果我们想要在构造函数中使用依赖注入,我们可以将依赖项作为参数传递给构造函数 。这样做的好处是,我们可以将依赖项注入到类中,以便在类的其他方法中使用 。将依赖项注入到构造函数中的语法是 constructor(@InjectRepository(User) private UserRepository: Repository<User>) {}。这个语法使用了 NestJS 框架的依赖注入功能,它将 UserRepository 注入到了这个类中,以便在这个类的其他方法中使用。@InjectRepository(User) 是一个装饰器,它告诉 NestJS 框架需要注入一个名为 UserRepository 的依赖项,这个依赖项的类型是 Repository<User>。这个装饰器是由 NestJS 框架提供的,它可以让我们在类中使用依赖注入功能,从而更好地管理类之间的依赖关系。

随后在user.module.ts中添加如下代码:

python 复制代码
import { Module, ConsoleLogger } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserService } from './user.service';
import { User } from './models/user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [ConsoleLogger, UserService],
  exports: [UserService],
})
export class UserModule {}

把 UserService 注册到 providers 和 exports 里,

providers: [ConsoleLogger, UserService]: 在 providers 部分,定义了该模块提供的服务。ConsoleLogger 可以用于在模块中记录日志,而 UserService 是用户相关业务逻辑的提供者。

随后在app.controller.ts中编写代码

typescript 复制代码
import { Controller, Get } from '@nestjs/common';
import { UserService } from './modules/user/user.service';

@Controller()
export class AppController {
  constructor(private readonly userService: UserService) {}

  @Get('/create')
  async create(): Promise<boolean> {
    return await this.userService.create({
      name: '麦子',
      desc: '普通用户',
      tel: '18334331233',
      password: '123456',
      account: 'admin',
    });
  }
}

处理来自客户端的 HTTP 请求并调用相应的服务逻辑。

import { Controller, Get } from '@nestjs/common';: 从 @nestjs/common 模块中导入 Controller 和 Get 装饰器。Controller 装饰器用于定义控制器,而 Get 装饰器用于指定处理 HTTP GET 请求的路由处理方法。

import { UserService } from './modules/user/user.service';: 导入了一个名为 UserService 的服务,这个服务包含了与用户相关的业务逻辑。

@Controller(): 使用 @Controller 装饰器定义了一个 NestJS 控制器,这个控制器默认处理根路径。

constructor(private readonly userService: UserService) {}: 控制器的构造函数中注入了一个 UserService 实例,使得在控制器的方法中可以使用这个服务进行业务逻辑的处理。

@Get('/create'): 使用 @Get 装饰器定义了一个处理 HTTP GET 请求的路由。这个路由的路径是 /create。

async create(): Promise { ... }: 定义了一个名为 create 的异步方法,处理 /create 路由的请求。这个方法返回一个 Promise。

在这个方法内部,通过调用 this.userService.create(...),使用了之前注入的 UserService 来执行某些与用户相关的创建操作。这可能是在数据库中创建新用户的业务逻辑。

返回的结果是一个 Promise<boolean>,表示创建操作的结果。在这个例子中,它可能表示用户创建是否成功,返回 true 表示成功,false 表示失败。

这样,这个控制器就定义了一个处理 HTTP GET 请求的路由 /create,当访问这个路由时,它会调用 UserService 中的业务逻辑来执行用户创建操作。

最终url键入路径模拟get请求http://localhost:3000/create成功执行了插入操作

数据库中也可以看到

删除用户

在user.service.ts中编写删除用户的逻辑

typescript 复制代码
//   删除用户
async del(id: string): Promise<boolean> {
  const res = await this.UserRepository.delete(id);
  if (res && res.affected > 0) {
    return true;
  }
  return false;
}

async del(id: string): Promise<boolean>: 这是一个异步方法,表示它会返回一个Promise对象,其中包含了一个布尔值。id: string表示该方法接受一个字符串类型的参数,即要删除的用户的唯一标识。

const res = await this.UserRepository.delete(id);: 在方法内部,它使用UserRepository(一个TypeORM的仓库实例)来执行删除操作。UserRepository.delete(id)会根据提供的用户ID(id参数)从数据库中删除相应的用户记录。这是一个异步操作,所以使用了await关键字等待操作完成。

if (res && res.affected > 0) { return true; } return false;: 在删除操作完成后,方法会检查res(删除操作的结果)是否存在,并且res.affected属性(受影响的行数)是否大于0。如果删除操作成功(受影响的行数大于0),则返回true表示删除成功,否则返回false表示删除失败。

综上,这段代码表示一个异步方法,接受一个用户ID作为参数,在数据库中删除对应的用户记录。如果删除成功,方法返回true,否则返回false。这样的异步方法通常被用作服务层(Service)的一部分,在GraphQL Resolver 或者其他地方被调用,用于处理删除用户的业务逻辑。

然后在controller中编写删除用户的使用逻辑

python 复制代码
@Get('/delete')
  async del(): Promise<boolean> {
    return await this.userService.del('e7c3b2da-f36a-4cfc-9094-f1e09527d4c1');
  }

@Get('/delete'):这是一个装饰器,用于将该路由处理器绑定到 GET 请求的路径 /delete 上。当用户访问 /delete 路径时,这个路由处理器将被触发。当用户向服务器发送GET请求并访问路径/delete时,Nest.js框架会将请求映射到这个del()方法。

使用路由装饰器(比如@Get(), @Post(), @Put(), @Delete()等)来创建RESTful API的路由。这些装饰器帮助将路由处理器(Route Handlers)绑定到特定的HTTP请求方法(GET、POST、PUT、DELETE等)以及相应的路径上。

async del(): Promise<boolean>:这是一个异步函数,用于处理 GET 请求。函数名为 del,没有接受任何参数,返回一个 Promise,表示异步操作的结果为一个布尔值。

return await this.userService.del('e7c3b2da-f36a-4cfc-9094-f1e09527d4c1');:在这个路由处理器中,它调用了 userService 中的 del 方法,传递了一个特定的参数 'e7c3b2da-f36a-4cfc-9094-f1e09527d4c1' 给 del 方法。这个方法可能用于删除指定 ID 的用户或执行其他相关的删除操作。

async del(): Promise 中的 Promise 表示该路由处理器返回一个 Promise,该 Promise 最终会被解析为一个布尔值。当 this.userService.del 方法执行完成时,路由处理器将返回相应的结果(true 或 false),这个结果会在 HTTP 响应中被返回给客户端。路由处理器的返回值将根据 userService.del 方法的返回值决定。

修改用户

在user.service.ts中编写修改用户的逻辑

typescript 复制代码
//   修改用户
async update(id: string, entity: DeepPartial<User>): Promise<boolean> {
  const res = await this.UserRepository.update(id, entity);
  if (res.affected > 0) {
    return true;
  }
  return false;
}

async update(id: string, entity: DeepPartial<User>): Promise<boolean>:这是一个异步方法,用于接收两个参数,id 表示要修改的用户的唯一标识,entity 是一个包含要更新用户信息的部分实体对象。DeepPartial 是一种通用类型,用于将类型 T 中的所有属性设置为可选(optional)。这意味着 DeepPartial 类型可以接受与类型 T 相同的属性,但这些属性都是可选的。

this.UserRepository.update(id, entity):在这行代码中,它调用了 UserRepository 的 update 方法,用于更新数据库中指定 id 的用户信息。UserRepository 可能是一个 TypeORM 中用于操作用户实体的 Repository 对象。

const res = await this.UserRepository.update(id, entity);:update 方法返回一个包含有关更新操作结果的对象。在这里,使用 await 关键字等待更新操作完成,并将结果保存在 res 变量中。

if (res.affected > 0) { return true; }:在更新操作成功后,update 方法返回一个包含 affected 属性的结果对象,该属性表示受影响的行数。如果受影响的行数大于 0,说明更新成功,此时返回 true 表示更新操作成功。

return false;:如果受影响的行数为 0,说明没有找到对应的用户进行更新,返回 false 表示更新操作失败。

所以,这段代码的作用是尝试更新数据库中指定 id 的用户信息,如果成功更新(即受影响的行数大于 0),则返回 true,否则返回 false。

可以在controller中编写使用逻辑

typescript 复制代码
 @Get('/update')
  async update(): Promise<boolean> {
    return await this.userService.update(
      '52a53cd2-3672-49e8-bd12-d9597ac5a2e1',
      {
        tel: '18342990089',
      },
    );
  }

@Get('/update'): 使用 @Get 装饰器定义了一个处理 HTTP GET 请求的路由。这个路由的路径是 /update。

async update(): Promise<boolean> { ... }: 定义了一个异步方法,名为 update,用于处理 /update 路由的请求。这个方法返回一个 Promise。

在方法内部,通过调用 this.userService.update(...),使用了注入的 UserService 来执行某些与用户相关的更新操作。这可能是在数据库中更新现有用户的业务逻辑。

传递给 update 方法的参数是用户的唯一标识符(在这里是 '52a53cd2-3672-49e8-bd12-d9597ac5a2e1')和一个包含要更新的用户属性(在这里是 { tel: '18342990089' }')。

返回的结果是一个 Promise,表示更新操作的结果。在这个例子中,它可能表示用户更新是否成功,返回 true 表示成功,false 表示失败。

这样,当访问 /update 路由时,控制器将调用 UserService 中的业务逻辑来执行用户更新操作,根据返回的结果决定是否返回 true 或 false。这种模式允许通过 HTTP 请求触发后端服务的更新操作,例如在数据库中修改用户信息。

查询用户

user.service.ts中编写查询用户的逻辑,定义了一个 find 方法,用于在 NestJS 应用中查找用户

csharp 复制代码
//   查找用户
  async find(id: string): Promise<User> {
    const res = await this.UserRepository.findOne({
      where: {
        id,
      },
    });
    return res;
  }

async find(id: string): Promise<User>: 这是一个异步方法,被命名为 find,接受一个字符串类型的参数 id,并返回一个 Promise。该方法用于根据用户的唯一标识符(通常是用户的 ID)来查找用户。

const res = await this.UserRepository.findOne({ where: { id } });: 在方法内部,通过使用 this.UserRepository(可能是通过 NestJS 中的 TypeORM 模块注入的数据库存储库)调用了 findOne 方法。这个方法用于在数据库中查找符合指定条件的单个实体。

{ where: { id } } 表示查询的条件,这里指定了要查找的用户的 id。

await 用于等待数据库查询操作的完成,确保在继续执行下一行代码之前等待查询结果。

查询结果被赋值给 res 变量。

return res;: 返回查询结果。在这个例子中,res 可能是找到的用户对象,或者如果没有找到匹配的用户,则为 undefined。

总体而言,这个 find 方法用于在数据库中查找特定 ID 的用户。在 NestJS 中,通常会使用 ORM(例如 TypeORM)提供的存储库(Repository)来执行数据库操作,这样可以更轻松地与数据库进行交互。

在controller中编写处理查找用户的逻辑,NestJS 控制器中的一个路由处理方法,用于处理 HTTP GET 请求,并调用服务中的 find 方法来查找用户。

csharp 复制代码
@Get('/find')
  async find(): Promise<User> {
    return await this.userService.find('22820297-e288-42ba-aadf-3a4062c5c3cb');
  }

@Get('/find'): 使用 @Get 装饰器定义了一个处理 HTTP GET 请求的路由。这个路由的路径是 /find。

async find(): Promise: 定义了一个异步方法,名为 find,不接受任何参数,返回一个 Promise。这个方法用于处理 /find 路由的请求。

return await this.userService.find('22820297-e288-42ba-aadf-3a4062c5c3cb');: 在方法内部,通过调用 this.userService.find 方法,使用了注入的 UserService 来执行查找用户的操作。指定了一个用户的唯一标识符(在这里是 '22820297-e288-42ba-aadf-3a4062c5c3cb')作为参数。

await 用于等待 this.userService.find 方法的执行结果,确保在继续执行下一行代码之前等待查找操作的完成。

返回的结果是一个 Promise,表示找到的用户对象。

这样,当访问 /find 路由时,控制器将调用 UserService 中的 find 方法来查找特定 ID 的用户,并将结果返回给客户端。这种模式允许通过 HTTP 请求触发后端服务的查询操作,返回特定用户的信息。

相关推荐
秦jh_8 分钟前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑21320 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy21 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与2 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun2 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss