MyBatis <collection> 配置嵌套查詢,主查詢執行正常,但關聯的 select="findStudent" 從未被調用。
<select id="findGrade" parameterType="int" resultMap="test">
select * from grade where id=#{id}
</select>
<resultMap id="test" type="com.hs.Entity.Grade">
<collection property="student" javaType="list" ofType="com.hs.Entity.Student"
select="findStudent" column="gradeId"/>
</resultMap>
<select id="findStudent" parameterType="int" resultType="com.hs.Entity.Student">
selcet * from student where id=#{id} -- 拼寫錯誤:selcet
</select>
selcet → select,導致語句解析失敗,MyBatis 靜默忽略或拋異常被吞噬。
column="gradeId" 必須與主查詢結果集列名一致(或別名)。parameterType 需與傳入參數類型一致(此處為 int)。<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
若 lazyLoadingEnabled=false,集合會立即加載;為 true 時需觸發 getter 才查詢。測試時需調用 grade.getStudent()。
property="student" 需與實體類字段名完全一致(含大小寫)。ofType 指定泛型類型,需為全限定名或別名。select="findStudent" 若不在同一 mapper 命名空間,需寫全限定 ID:namespace.findStudent。
<mapper namespace="com.hs.mapper.GradeMapper">
<select id="findGrade" parameterType="int" resultMap="test">
select id, name, grade_id as gradeId from grade where id=#{id}
</select>
<resultMap id="test" type="com.hs.Entity.Grade">
<id property="id" column="id"/>
<result property="name" column="name"/>
<collection property="student" javaType="ArrayList" ofType="com.hs.Entity.Student"
select="findStudent" column="gradeId"/>
</resultMap>
<select id="findStudent" parameterType="int" resultType="com.hs.Entity.Student">
select * from student where grade_id = #{id}
</select>
</mapper>
debug 級別),觀察 SQL 執行情況。findStudent 語句,驗證 SQL 正確性。Grade.student 字段是否有 @Setter 或公共 setter 方法。MyBatis <collection> 不執行多由SQL 語法錯誤、參數映射不匹配、延遲加載未觸發、命名空間缺失導致。本例核心是嵌套查詢 SQL 寫成 selcet。排查時按:SQL 語法 → 參數映射 → 加載策略 → 命名空間 → 實體映射 順序逐項驗證,開啟調試日誌可事半功倍。