原文:MyBatis中的collection兩種使用方法
轉載是爲記錄一波,防止失聯(2021年9月1日20:18:03)
表關係: 問題表
1==>n 問題選項表
,
需求: 查詢問題
時候,聯查出來問題選項
//問題 實體類 public class Question { private String id; //ID private String content; //問題 private String type; //問題類型 1:單選,2:多選,3:問答 private Integer sort; //排序 private List<QuestionOption> options; //問題選項 *** 問題表裏不需要有這個屬性對應的字段 //... }
//問題選項 實體類 public class QuestionOption{ private String id; //ID private String qid; //問題ID *** 問題選項表裏需要有這個屬性對應的字段 private String content; //選項 private Integer sort; //排序 //... }
方式一: 代碼複用性高, 主表分頁查詢正確
QuestionMapper.xml
<mapper namespace="com.xxx.modules.xxx.mapper.QuestionMapper"> <resultMap id="BaseResultMap" type="com.xxx.modules.xxx.entity.Question" > <id column="id" property="id" jdbcType="VARCHAR" /> <result column="content" property="content" jdbcType="VARCHAR" /> <result column="type" property="type" jdbcType="VARCHAR" /> <result column="sort" property="sort" jdbcType="INTEGER" /> <collection property="options" javaType="java.util.ArrayList" ofType="com.xxx.modules.xxx.entity.QuestionOption" select="com.xxx.modules.xxx.mapper.QuestionOptionMapper.selectList" column="{qid=id,sort=sort}" /> <!-- qid/sort是定義的變量名, id/sort是主表的字段id/sort, 先查出主表的結果, 然後主表記錄數是幾 就執行幾次 collection 的select, javaType和ofType 寫不寫都行, select的值: 對應xml的namespace + 對應xml中的代碼片段的id, column作爲select語句的參數傳入,如果只傳一個參數id可以簡寫: column="id" --> </resultMap> <!-- 查詢列表 --> <select id="selectList" resultMap="BaseResultMap"> SELECT pq.id, pq.content, pq.type, pq.sort FROM question AS pq <where> </where> </select>
QuestionOptionMapper.xml
<mapper namespace="com.xxx.modules.xxx.mapper.QuestionOptionMapper"> <!-- 查詢列表 --> <select id="selectList" resultType="QuestionOption"> SELECT pqo.id, pqo.content, pqo.sort FROM question_option AS pqo <where> pqo.qid = #{qid} <!-- 變量名 qid 對應上文的 qid --> <!-- 如果上文中 collection只傳一個參數column="id",只要類型匹配,在這裏隨便寫個變量名就可以取到值 #{xyz} --> </where> </select>
方式二: 只需要執行一次sql查詢, 主表分頁查詢不正確
QuestionMapper.xml
<mapper namespace="com.xxx.modules.xxx.mapper.QuestionMapper"> <resultMap id="BaseResultMap" type="com.xxx.modules.xxx.entity.Question" > <id column="id" property="id" jdbcType="VARCHAR" /> <result column="content" property="content" jdbcType="VARCHAR" /> <result column="type" property="type" jdbcType="VARCHAR" /> <result column="sort" property="sort" jdbcType="INTEGER" /> <collection property="options" javaType="java.util.ArrayList" ofType="com.xxx.modules.data.entity.QuestionOption"> <id column="o_id" property="id" jdbcType="VARCHAR" /> <result column="o_content" property="content" jdbcType="VARCHAR" /> <result column="o_sort" property="sort" jdbcType="INTEGER" /> </collection> <!-- 列的別名 o_id,o_content,o_sort , 起別名是因爲主子表都有這幾個字段 這裏要寫 ofType, javaType還是可以不寫 --> </resultMap> <!-- 查詢列表 --> <select id="selectList" resultMap="BaseResultMap"> SELECT pq.id, pq.content, pq.type, pq.sort ,pqo.id AS oid ,pqo.content AS ocontent ,pqo.sort AS osort <!-- 聯查子表字段,起別名 --> FROM question AS pq LEFT JOIN question_option pqo ON pq.id = pqo.qid <!-- 聯查子表 --> <where> </where> </select>
注意: 主子表要查詢出來的字段名重複,要起別名