TypeORM操作MySQL如何实现column like模糊匹配代替等值查询
TypeORM 不存在可以直接重写字段默认查询规则的 @BeforeLoad 类钩子,你之前添加的 @Index 注解仅用于配置数据库索引,和查询时的匹配逻辑无关,不生效是正常现象。
下面是可行的实现方案:
方案1:直接在查询方法中处理参数(最推荐)
直接在现有分页方法中对 where 参数做预处理,当存在 name 字段时,将其替换为 TypeORM 内置的 Like 运算符即可,改动最小且逻辑可控:
// 首先从 typeorm 导入 Like 运算符 import { Like } from 'typeorm'; async findAll({ page, count, ...where }: CategorySelectFilter): Promise<Category[]> { // 新增name字段模糊匹配处理逻辑 if (where.name) { where.name = Like(`%${where.name}%`); } return this.categoryRepository.find({ where, take: count, skip: (page - 1) * count, order: { createdAt: 'DESC', }, }); }
方案2:封装通用处理工具(多查询场景复用)
如果有多个查询方法都需要用到 name 模糊匹配规则,可以把处理逻辑封装成独立的工具函数,避免重复代码:
// category.util.ts import { Like } from 'typeorm'; export function formatCategoryQueryWhere(where: Record<string, any>) { if (where.name) { where.name = Like(`%${where.name}%`); } // 后续其他字段的查询规则修改也可以统一在这里扩展 return where; }
在查询方法中直接调用即可:
async findAll({ page, count, ...where }: CategorySelectFilter): Promise<Category[]> { const processedWhere = formatCategoryQueryWhere(where); return this.categoryRepository.find({ where: processedWhere, take: count, skip: (page - 1) * count, order: { createdAt: 'DESC', }, }); }
方案3:全局生效(Subscriber 方案)
如果你需要所有涉及 Category 实体的查询,只要携带 name 参数就自动走模糊匹配,可以用 TypeORM 的 Subscriber 监听查询事件做全局处理:
import { EventSubscriber, EntitySubscriberInterface, SelectQueryBuilder } from 'typeorm'; import { Category } from './category.entity'; @EventSubscriber() export class CategorySubscriber implements EntitySubscriberInterface<Category> { listenTo() { return Category; } beforeSelectQuery(event: { queryBuilder: SelectQueryBuilder<Category> }) { const { queryBuilder } = event; const params = queryBuilder.getParameters(); // 匹配name参数的等值条件,替换为模糊查询 if (params.name) { queryBuilder.andWhere('Category.name LIKE :name', { name: `%${params.name}%` }); // 移除原有等值条件 queryBuilder.expressionMap.wheres = queryBuilder.expressionMap.wheres.filter( item => !item.condition.includes('Category.name =') ); } } }
注意该方案存在局限性:如果存在需要 name 等值匹配的业务场景会被影响,且查询别名和实体名不一致时需要调整匹配逻辑,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Oki
相关产品推荐
相关产品推荐

