从TypeORM(MySQL)取回含双空格字符串异常问题求助
TypeORM从MySQL取回含双空格字段时的匹配异常及解决方法
问题现象
通过TypeORM从MySQL获取对象时,若字符串字段值包含双普通空格,取回的内容表面看是双空格,但实际字符编码与原始值不一致,导致用该值作为JavaScript对象属性访问器时返回undefined。示例代码如下:
const field_name_obj = { field_name : "some name" // 两个普通空格 } const obj = { "some name" : "value" } // 假设已执行typeORM.save(field_name_obj) const get = await typeORM.findOneBy(field_name_obj); console.log(get.field_name) // 控制台显示"some name" console.log(obj[get.field_name]) // 输出undefined console.log(obj[field_name_obj.field_name]) // 输出"value" console.log(obj["some name"]) // 输出"value"
当字段值改为单空格时,obj[get.field_name]能正常返回值。对应表信息:
Engine: InnoDB Table collation: utf8mb4_unicode_ci
错误原因
核心问题来自MySQL的utf8mb4_unicode_ci排序规则:该规则属于语义校对规则,会对字符做等价折叠处理——它将不同类型的空白字符(比如普通空格U+0020、非断空格U+00A0等)视为语义等价。在存储或查询过程中,MySQL可能将连续的普通空格转换为其他空白字符,或在返回结果时做归一化处理,导致取回的字符串视觉上是双空格,但实际字符编码与原始的双普通空格不一致。TypeORM仅原样返回MySQL的结果,因此引发了JavaScript中字符串不匹配的问题。
解决方法
方法1:使用严格二进制校对规则
将字段的校对规则改为utf8mb4_bin,该规则严格按照字符的二进制编码存储和比较,不会对空白字符做等价转换,从根源避免问题:
- 修改数据库字段:
ALTER TABLE your_table MODIFY COLUMN field_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
- 同步TypeORM实体配置(若使用装饰器):
import { Column, Entity } from "typeorm"; @Entity() export class YourEntity { @Column({ type: "varchar", collation: "utf8mb4_bin" }) field_name: string; }
方法2:取回数据后标准化空白字符
若无法修改数据库配置,可在取回数据后,将字符串中所有Unicode空白字符统一替换为普通空格:
const get = await typeORM.findOneBy(field_name_obj); // 替换所有空白字符为普通空格 const normalizedField = get.field_name.replace(/\s/g, " "); console.log(obj[normalizedField]); // 正常返回"value"
正则/\s/g会匹配所有Unicode空白类字符,确保转换后的字符串与代码中定义的属性名完全一致。
内容的提问来源于stack exchange,提问作者jiuwo
相关产品推荐
相关产品推荐

