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 请求触发后端服务的查询操作,返回特定用户的信息。

相关推荐
腾讯云云开发26 分钟前
小程序数据库权限管理,一看就会!——CloudBase新手指南
前端·数据库·微信小程序
多则惑少则明1 小时前
Vue开发系列——自定义组件开发
前端·javascript·vue.js
用户250694921611 小时前
next框架打包.next文件夹部署
前端
程序猿小蒜1 小时前
基于springboot的校园社团信息管理系统开发与设计
java·前端·spring boot·后端·spring
一叶难遮天1 小时前
开启RN之旅——前端基础
前端·javascript·promise·js基础·es6/ts·npm/nrm
申阳1 小时前
Day 4:02. 基于Nuxt开发博客项目-整合 Inspira UI
前端·后端·程序员
程序猿_极客1 小时前
【期末网页设计作业】HTML+CSS+JavaScript 猫咪主题网站开发(附源码与效果演示)
前端·css·html·课程设计·网页设计作业
IT古董1 小时前
【前端】从零开始搭建现代前端框架:React 19、Vite、Tailwind CSS、ShadCN UI 完整实战教程-第1章:项目概述与技术栈介绍
前端·react.js·前端框架
有点笨的蛋1 小时前
从零搭建小程序首页:新手也能看懂的结构解析与实战指南
前端·微信小程序
爱宇阳1 小时前
Vue3 前端项目 Docker 容器化部署教程
前端·docker·容器