Node 系列(四)按条件查询、模糊查询以及分页 您所在的位置:网站首页 按条件查询数据库 Node 系列(四)按条件查询、模糊查询以及分页

Node 系列(四)按条件查询、模糊查询以及分页

2024-06-03 18:00| 来源: 网络整理| 查看: 265

前言

上一篇,我们介绍了数据库的增删改查这些基础操作,但是需求中,经常会需要我们多个可选条件查询以及分页,那么接下来,我们就需要去了解分页查询以及按条件查询了。

分页

我们先来了解一下分页。从 MidWay 的文档中,我们可以发现,使用 QueryBuilder 可以构建几乎任何复杂的 SQL 查询,那么接下来,我们就简单的了解一下吧。

什么是 QueryBuilder QueryBuilder 是 TypeORM 最强大的功能之一 ,它允许你使用优雅便捷的语法构建 SQL 查询,执行并获得自动转换的实体。 简单来讲,就是 TypeORM 底层封装了很多方法,可以使用封装好的方法实现一些复杂的 SQL 查询。 创建和使用 QueryBuilder创建 QueryBuilder

创建 QueryBuilder 有三种方式:使用 connection 、使用 entity manager 、使用 repository ,这里我们采用第二种方式,使用 entity manager 来创建 QueryBuilder 。

之前我们已经创建过 UserEntity ,这里我们还是拿这个来作为例子。使用 createQueryBuilder() 方法,来创建 QueryBuilder 。

12345678910111213141516171819202122// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser() { // createQueryBuilder() 创建 QueryBuilder , 这里的 user 是一个常规的 SQL 别名 const db = this.userModel.createQueryBuilder('user'); }} 使用 QueryBuilder 获取值 从数据库中获取单个结果,使用 getOne() 从数据库中获取多个结果,使用 getMany() 从数据库中获取多个结果以及数据总数,使用 getManyAndCount() 123456789101112131415161718192021// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser() { // getMany() 可以直接返回数据库中所有的数据 const db = this.userModel.createQueryBuilder('user').getMany(); }}

我们到这里,已经学会了创建 QueryBuilder 以及使用 QueryBuilder 获取数据库的数据了,那么接下来,我们就来看分页了。

使用分页

在大多数的需求中,我们都会使用分页的功能,这里提供了 take() 和 skip() 方法来辅助我们实现分页的功能

take(): 返回前多少个数据,这里接收一个 number 类型的参数,表示我们需要拿多少条数据 skip(): 返回除了前多少个数据以外的数据,同样接收一个 number 类型的参数

我们组合这些方法,就可以实现一个分页的功能,如下:

123456789101112131415161718192021222324252627282930313233343536// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser(pageNumber: number, pageSize: number) { /** * skip() 和 take() 组合,实现分页功能 * 这里使用的是 getManyAndCount() ,而不是 getMany() , * 因为我们在接口中,一般还需要查询出数据库中的数据总条数,并在接口中返回 * getManyAndCount() 返回的数据结果类似 * [ * [ * UserEntity { id: 8, name: 'Avery', password: '123456' }, * UserEntity { id: 16, name: 'Avery', password: '111111' } * ], * 2 * ] */ const db = this.userModel.createQueryBuilder('user') .skip((page - 1) * size) .take(size) .getManyAndCount(); }} 按条件查询

分页写完了,但是一般情况下,我们的查询都会携带多个可选的查询条件去进行数据查询,接下来我们就把这些查询条件加进去吧我们先在 interface.ts 中定义一个接口

12345678910// src/interface.ts/** * 这里的 ? 表示的是可选参数, * 我目前用的 user 表,字段不多,所以查询条件也只有一个 name * 如果查询条件有多个,可以继续在 name 后边去添加 */export interface Params { name?: string;}

准备工作完成了,就该去使用了,这里我们介绍一个 andWhere() 方法,它的作用就是添加查询条件,具体用法如下:

12345678910111213141516171819202122232425262728293031323334353637// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';import { Params } from '../interface';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser(pageNumber: number, pageSize: number, param: Params) { /** * param: 是我们的查询条件 * 可选的查询条件,意味着,如果我传入了查询条件,则返回的数据是符合查询条件的数据, * 否则,返回的则是所有的数据 * 所以这里我们需要进行判断,看是否有查询条件,有查询条件的话,就用 andWhere() 方法把查询语句加入进入 * andWhere('user.name = :name', { name: `${params.name}` })参数说明: * name是参数名,值在对象中指定: {name:`${params.name}`} */ const db = this.userModel.createQueryBuilder('user') if (params.name != null && params.name != '') { db.andWhere('user.name = :name', { name: `${params.name}` }); } const res = await db .select() .skip((page - 1) * size) .take(size) .getManyAndCount(); }} 模糊查询

模糊查询和按条件查询类似,只不过多了个关键字 LIKE ,并且使用 setParameters 来设置模糊查询的关键字。

1234567891011121314151617181920212223242526272829303132333435363738394041// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';import { Params } from '../interface';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser(pageNumber: number, pageSize: number, param: Params) { /** * param: 是我们的查询条件 * 可选的查询条件,意味着,如果我传入了查询条件,则返回的数据是符合查询条件的数据, * 否则,返回的则是所有的数据 * 所以这里我们需要进行判断,看是否有查询条件,有查询条件的话,就用 andWhere() 方法把查询语句加入进入 * andWhere('user.name = :name', { name: `${params.name}` })参数说明: * name是参数名,值在对象中指定: {name:`${params.name}`} * setParameters 设置模糊查询的关键字 */ const db = this.userModel.createQueryBuilder('user') if (params.name != null && params.name != '') { // db.andWhere('user.name = :name', { name: `${params.name}` }); db.andWhere('user.name Like :param').setParameters({ param: '%' + params.name + '%', }); } const res = await db .select() .skip((page - 1) * size) .take(size) .getManyAndCount(); }}

到这里,我们的分页、模糊查询以及按条件查询数据就完成了,但是会发现一个问题, getManyAndCount() 返回的数据总条数是数组的第二个元素,和我们所需要的格式不符,所以我们接下来先把数据格式修改一下。我们在 constant 里新建一个 pageInfo.ts 文件,然后封装一个 PageInfo 的泛型类,如下:

12345678910111213141516171819202122232425262728293031323334353637383940414243// src/constant.pageInfo.ts/** * 首先,我们想要的数据格式为这种的: * { * pageInfo: { * pageSize: 1, * pageNumber: 10, * total: 100 * }, * data: [] * } * 所以我们定义类 2 个类,在 PageInfo 这个类里,引用 Page 这个类,就可以得到想要的数据格式了 */export class PageInfo { pageInfo: Page; data: T[]; static pageLis( pageNumber: number, pageSize: number, result: [T[], number] ): PageInfo { const info = new PageInfo(); info.pageInfo = Page.info(pageNumber, pageSize, result[1]); info.data = result[0]; return info; }}class Page { pageNumber: number; pageSize: number; total: number; static info(pageNumber: number, pageSize: number, total: number): Page { const info = new Page(); info.pageNumber = pageNumber; info.pageSize = pageSize; info.total = total; return info; }}

这个类我们是在 Service 层去使用的,如下:

1234567891011121314151617181920212223242526// src/service/user.service.tsimport { Inject, Provide } from '@midwayjs/decorator';import { InjectEntityModel } from '@midwayjs/orm';import { UserEntity } from '../entity/user.entity';import { Repository } from 'typeorm';import { ILogger } from '@midwayjs/logger';import { Params } from '../interface';import { PageInfo } from '../constant/pageInfo';@Provide('')export class UserService { @Inject() logger: ILogger; @InjectEntityModel(UserEntity) userModel: Repository; // 查询数据 async findUser(pageNumber: number, pageSize: number, params: Params) { const db = this.userModel.createQueryBuilder('user') .skip((page - 1) * size) .take(size) .getManyAndCount(); return PageInfo.pageLis(size, page, res); }}

这样,我们在 Controller 层,写一个路由直接调用该查询方法,就可以得到我们想要的数据格式了。

123456@Post('/list') async userList(@Body() param: Params) { const result = await this.user.findUser(1, 5, param); return ResultRtn.ofSuccess(result); } 总结

到此,我们的按条件查询以及数据分页就完成了,完成的代码已上传到个人 【GitHub】,有需要可自行下载关于 QueryBuilder 的 API ,可以从 这里 查看

本文作者: Gladysdrea 本文链接: https://gladysdrea.github.io/blogs/2022/05/17/Node系列/Node系列(四)按条件查询以及分页/ 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有