大家好,我是一航;
昨天一位粉丝朋友和我聊天,说遇到了一个莫名奇妙的问题,让我帮着分析一下;经过他的一轮描述,发现是一个HashMap元素顺序小’坑’;但是一不留神,老司机也容易在这里翻车。
一句话来描述一下他的问题:明明我数据库语句使用了Order by进行了排序,日志中也看到数据是按顺序查出来了,但业务层收到数据依然还是乱序的呢?;
整个过程,确实出现了好几处的迷惑现象,影响了他对问题的判断;下面就从一个小案例加上源码分析,来看看到底发生了什么。
问题复现
为了方便说明问题,这里用一个简单的业务场景来模拟一下;
数据表
一张简单的学生信息表
需求
需要按id顺序(order by id)获取出学号(student_id)对应的学生信息;为了方便业务层面根据学号获取数据,这位朋友采用了如下的数据格式,并用了HashMap在业务代码中接收数据:
{
"S000001": {
"name": "张三",
"student_id": "S000001",
"age": 7
},
"S000002": {
"name": "李四",
"student_id": "S000002",
"age": 7
},
"S000003": {
"name": "王五",
"student_id": "S000003",
"age": 8
},
"S000004": {
"name": "赵六",
"student_id": "S000004",
"age": 8
}
}
代码实现
-
Dao
@MapKey("student_id") HashMap<String, Object> getStudentId();
-
xml
<select id="getStudentMap" resultType="java.util.HashMap"> select student_id , `name` , age from student_info order by id </select>
-
测试用例
@Autowired StudentInfoMapper studentInfoMapper; @Test void map() { HashMap<String, Object> studentId = studentInfoMapper.getStudentMap(); studentId.forEach((id, studentInfo) -> log.info("学号:{} 信息:{}", id, JSON.toJSONString(studentInfo))); }
问题点
以上代码的执行日志;
当学号是如下数据再查询的时候,整个数据查询和使用都是没有任何问题的
==> Preparing: select student_id , `name` , age from student_info order by id
==> Parameters:
<== Columns: student_id, name, age
<== Row: S000001, 张三, 7
<== Row: S000002, 李四, 7
<== Row: S000003, 王五, 8
<== Row: S000004, 赵六, 8
<== Total: 4
Closing non transactional SqlSession
StudentTest : 学号:S000001 信息:{
"name":"张三","student_id":"S000001","age":7}
StudentTest : 学号:S000002 信息:{
"name":"李四","student_id":"S000002","age":7}
StudentTest : 学号:S000003 信息:{
"name":"王五","student_id":"S000003","age":8}
StudentTest : 学号:S000004 信息:{
"name":"赵六","student_id":"S000004","age":8}
但是当把学号换成以下数据之后:
根据查询结果和输出日志可以看到