TypeORM对接MSSQL时如何实现UUID大小写不敏感匹配及统一小写存取
解决方案
方案1:全局统一UUID小写存取(推荐)
直接通过TypeORM的列转换器实现存入、读取时自动转换为小写,从根源上统一格式,不需要修改业务查询代码。
修改实体定义中所有UUID类型的列,添加transformer配置即可,示例如下:
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn, OneToMany } from "typeorm"; @Entity() export class Application { // 主键UUID添加转换器 @PrimaryGeneratedColumn("uuid", { transformer: { // 存入数据库前转小写 to: (value: string) => value?.toLowerCase(), // 从数据库读取后转小写(抵消MSSQL默认返回大写的问题) from: (value: string) => value?.toLowerCase(), } }) id: string; @Column() name: string; @Column("bigint") dateCreated: number; @Column() status: string; @ManyToOne(type => Owner, owner => owner.applications) @JoinColumn({ name: "ownerId" }) owner: Owner; // 外键UUID同样添加转换器 @Column({ transformer: { to: (value: string) => value?.toLowerCase(), from: (value: string) => value?.toLowerCase(), } }) ownerId: string; @OneToMany(type => User, user => user.application) users: User[]; @OneToMany(type => ChatRoom, chatRoom => chatRoom.application) chatRooms: ChatRoom[]; }
配置完成后:
- 所有传入的UUID参数会自动转小写再执行查询,和库内小写存储的格式完全匹配
- 查询返回的UUID字段会自动转小写,不需要额外处理返回结果
- 新写入的UUID也会统一转小写存入数据库,和存量数据格式一致
方案2:仅实现单次查询大小写不敏感
如果不想修改实体定义,可以使用TypeORM的Raw函数自定义查询条件,调用MSSQL的LOWER函数做大小写统一匹配,注意使用参数化写法避免SQL注入:
import { Raw } from 'typeorm'; let application = await applicationRepo.findOne({ where: { id: Raw((alias) => `LOWER(${alias}) = LOWER(:targetId)`, { targetId: model.id }), ownerId: Raw((alias) => `LOWER(${alias}) = LOWER(:ownerId)`, { ownerId: res.locals.owner.id }) } });
补充方案:数据库层面全局配置大小写不敏感
你也可以直接修改MSSQL对应UUID列的排序规则为大小写不敏感(CI后缀的排序规则,比如SQL_Latin1_General_CP1_CI_AS),修改后数据库执行UUID匹配时会自动忽略大小写,不需要修改业务代码。
内容的提问来源于stack exchange,提问作者Alvin Stefanus
相关产品推荐
相关产品推荐

