java程序LinkedHashMap属性作为存到一个json列, 插入和读取key的顺序是否保持一致?
不能保证一致。 LinkedHashMap 的插入顺序在「写入 JSON 列 → 再读出」后通常会丢。
原因
链路分两段:
- Java 侧:
LinkedHashMap本身保序;Jackson/Gson 序列化成 JSON 文本时,一般也会按插入顺序输出。 - 数据库侧(关键):MySQL / TiDB 的
JSON类型会把对象存成二进制格式,并为加速查找对 object 的 key 排序。读出来时是排序后的顺序,不是你当初的插入顺序。
TiDB 代码里写对象时会按 key 排序:
json_binary.goLines 873-875
slices.SortFunc(fields, func(i, j field) int {
return cmp.Compare(i.key, j.key)
})
MySQL 文档也明确:JSON 对象会排序 keys,且该顺序不保证跨版本稳定。
因此:即使 Java 用 LinkedHashMap,落库后再反序列化,key 顺序也不可依赖。
若业务必须保序
- 存成 JSON 数组(数组有序),例如
[{"k":"a","v":1},{"k":"b","v":2}],或[["a",1],["b",2]] - 或用 TEXT/VARCHAR 存原始 JSON 文本(不做 binary JSON 规范化),再自行解析
- 不要把顺序语义建立在 JSON object 的 key 顺序上
建议你用TiDB的JSON列时,默认不保证键顺序一致性。如果一定要保持顺序,可以试试以下方案:
-
在Java端用Jackson或Gson序列化时指定
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,但这样只能按字母序排序。 -
更靠谱的做法:把LinkedHashMap直接转成字符串(如JSON字符串)存入VARCHAR列,读取时再反序列化成LinkedHashMap,这样顺序完全由你控制。