問題描述
最近遇到一個查詢列表問題,發現實際數據庫查詢 4 條數據,但是經過程序就是 3 條,一開始懷疑是不是自己程序做了去重啥的,一頓排查猛如虎發現并沒有,后來看了下 resultMap 的機制的坑~
<resultMap id="userVO" type="com.xx.UserVO"><result column="userInfo1" jdbcType="VARCHAR" property="userInfo1" /><result column="userInfo2" jdbcType="VARCHAR" property="userInfo2" /><result column="userInfo3" jdbcType="VARCHAR" property="userInfo3" /><result column="cardNo" jdbcType="VARCHAR" property="cardNo" /><association property="userDetailVO" javaType="com.xx.UserDetailVO" resultMap="BaseResultMap"/>
</resultMap>
- 查詢出來的 total 是 4,但是程序查詢出來的實際數據是 3
原因分析
SQL 查詢出來的數據
userInfo1 userInfo2 userInfo3 userDetailVO
1 2 3 {4,5}
1 2 4 {5,6}
1 2 3 {6,7}Mybatis 處理完之后的數據
userInfo1 userInfo2 userInfo3 userDetailVO
1 2 4 {5,6}
1 2 3 {6,7}
可以知道,我這里是查詢一個用戶信息 + 用戶詳情組合。但是 resultInfo1-3 可能會有重復,但是詳情是各有不同的,于是 mybatis 就認定相同 resultInfo1-3 相同的是一條數據
于是原本應該是 total = 3 的,實際上查出來的數據只有兩條,被 mybatis 做了去重處理
解決方案
- 在 UserVO 里面加上一個唯一確定的主鍵,那么這個時候就不存在重復
- 在 UserVO 里面加上一個能與現在字段構成聯合主鍵的字段,這個時候也不會存在重復,被過濾的情況
原來 Mybatis 的 resultMap 有一個去重機制,它可以幫助我們在查詢結果中去除重復的數據。這個機制的核心是使用了一個叫做"discriminator"的標簽來設置區分不同結果的標識
案例 DEMO
在 resultMap 中添加 discriminator 標簽,設置該標簽的 column 屬性和 javaType 屬性,用于確定區分不同結果的標識是哪個字段,并且該字段的數據類型是什么
<resultMap id="userResultMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><result property="email" column="email" /><discriminator column="type" javaType="string"><case value="1" resultMap="studentResultMap" /><case value="2" resultMap="teacherResultMap" /></discriminator>
</resultMap>
在各個子 resultMap 中設置唯一區分標識的值,并且保證不同的 resultMap 區分的標識值不同
<resultMap id="studentResultMap" type="Student"><id property="id" column="id" /><result property="studentName" column="student_name" /><result property="studentAge" column="student_age" />...
</resultMap><resultMap id="teacherResultMap" type="Teacher"><id property="id" column="id" /><result property="teacherName" column="teacher_name" /><result property="teacherAge" column="teacher_age" />...
</resultMap>
這樣,當查詢結果中有相同區分標識的數據時,Mybatis 就會將它們視為同一條數據,只返回其中的一條。通過這個機制,我們可以有效地去除重復數據,使查詢結果更加準確和具有可讀性