在Mybatis實現數據處理過程中,字段名符合數據庫的規則,屬性一般為駝峰規則,因此字段名和屬性名通常不一致,此時可以通過以下兩種方式對數據庫字段進行映射處理:
- 為字段起別名,保證和實體類中的屬性名一致
- 在滿足駝峰轉換規則時
在MyBatis的核心配置文件中設置一個全局配置信息mapUnderscoreToCamelCase,可以在查詢表中數據時,自動將數據庫字段名轉換為駝峰 - 通過resultMap進行字段映射處理
1 利用字段別名映射
List<Emp> listEmp();
<!--通過字段別名解決字段名和屬性名的映射問題--><select id="listEmp" resultType="Emp">select id, user_name as userName, pass_word as passWord, sex, dept_id as deptId from t_emp</select>
2 利用駝峰轉換規則映射
在Mybatis核心配置文件中,設置全局的駝峰轉換,此時框架會根據駝峰規則自動將數據庫字段和實體屬性進行映射。
- 核心配置
<settings><!-- 將表中的下劃線字段自動映射為駝峰命名的屬性字段 --><setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
- 數據查詢
<!--通過駝峰配置,此時Mybatis框架會自動將字段和屬性進行映射,如user_name映射到userName屬性上。-->
<select id="listEmp" resultType="Emp">select id, user_name, pass_word, sex, dept_id from t_emp
</select>
此處resultType直接使用實體類別名,因為存在如下的配置:
<typeAliases><!--typeAlias:設置某個具體的類型的別名屬性:type:需要設置別名的類型的全類名alias:設置此類型的別名若不設置此屬性,該類型擁有默認的別名,即類名且不區分大小寫; 若設置此屬性,此時該類型的別名只能使用alias所設置的值--><!--<typeAlias type="com.giser.mybatis.bean.User"></typeAlias>--><!--<typeAlias type="com.giser.mybatis.bean.User" alias="abc"></typeAlias>--><!--以包為單位,設置改包下所有的類型都擁有默認的別名,即類名且不區分大小寫--><package name="com.giser.pojo"/>
</typeAliases>
3 利用resultMap映射
<!--resultMap設置自定義映射關系id: 自定義映射的唯一標識type: 映射的實體類類型子標簽:id: 設置主鍵的映射關系result:設置普通字段的映射關系屬性:property: 設置映射關系中實體類的屬性column: 設置映射關系中表字段--><resultMap id="empMap" type="Emp"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /><result property="deptId" column="dept_id" /></resultMap><!--使用ResultMap解決字段名和屬性名的映射問題--><select id="listEmp" resultMap="empMap">select * from t_emp</select>
3.1 多對一映射
3.1.1 級聯映射
存在如下實體:
public class Dept {private Integer id;private String deptName;private String deptNo;// getter setter
}public class EmpDept {private Integer id;private String userName;private String passWord;private String sex;private Integer deptId;private Dept dept;// getter setter
}
List<EmpDept> listEmpDeptById(@Param("eid")Integer eid);
<select id="listEmpDeptById" resultMap="empDeptMap">select * from t_emp left join t_dept on t_emp.dept_id = t_dept.id where t_emp.id = #{eid}
</select>
此時需要級聯映射,如下:
<!--通過級聯屬性賦值
-->
<resultMap id="empDeptMap" type="EmpDept"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /><result property="deptId" column="dept_id" /><result property="dept.id" column="id" /><result property="dept.deptName" column="dept_name" /><result property="dept.deptNo" column="dept_no" />
</resultMap>
3.1.2 使用association實現多對一映射
如員工和部門的關系就是多對一,多個員工可能在同一個部門。此時可以通過上述的級聯屬性賦值方式進行映射,還可以通過association處理映射關系。
<!--通過association處理多對一映射關系
-->
<resultMap id="empDeptMapTwo" type="EmpDept"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /><result property="deptId" column="dept_id" /><!--association處理多對一的映射關系property: 需要處理多對一映射關系的實體屬性名javaType: 實體屬性的類型--><association property="dept" javaType="Dept"><id property="id" column="id" /><result property="deptName" column="dept_name" /><result property="deptNo" column="dept_no" /></association>
</resultMap><select id="listEmpDeptById" resultMap="empDeptMapTwo">select * from t_emp left join t_dept on t_emp.dept_id = t_dept.id where t_emp.id = #{eid}
</select>
3.1.3 使用association分步查詢實現多對一映射
List<EmpDept> listEmpDeptByStep(@Param("eid") Integer eid);
<!--多對一映射關系處理方式二:通過分步查詢
-->
<resultMap id="empDeptMapStep" type="EmpDept"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /><result property="deptId" column="dept_id" /><!--select :設置分步查詢的Sql的唯一標識(namespace.SQLId或mapper接口的全類名.方法名)column :設置分步查詢的條件--><association property="dept"
select="com.giser.mapper.DeptMapper.selectEmpAndDeptByStepTwo"column="dept_id"></association>
</resultMap><select id="listEmpDeptByStep" resultMap="empDeptMapStep">select * from t_emp left join t_dept on t_emp.dept_id = t_dept.id where t_emp.id = #{eid}
</select>
/*** 分步查詢第二步* @param deptId* @return*/
Dept selectEmpAndDeptByStepTwo(@Param("deptId")Integer deptId);
<select id="selectEmpAndDeptByStepTwo" resultType="Dept">select * from t_dept where id = #{deptId}
</select>
- 延遲加載
分步查詢的優點:可以實現延遲加載,但是必須在核心配置文件中設置全局配置信息:
lazyLoadingEnabled
:延遲加載的全局開關。當開啟時,所有關聯對象都會延遲加載
aggressiveLazyLoading
:當開啟時,任何方法的調用都會加載該對象的所有屬性。 否則,每個屬性會按需加載
此時就可以實現按需加載,獲取的數據是什么,就只會執行相應的sql。此時可通過association和collection中的fetchType
屬性設置當前的分步查詢是否使用延遲加載,fetchType=“lazy(延遲加載)|eager(立即加載)”。
在mybatis-config.xml中,開啟懶加載配置
<settings><!-- 開啟延遲加載 --><setting name="lazyLoadingEnabled" value="true" /></settings>
在映射關聯屬性時,設置fetchType=“lazy”
<!--多對一映射關系處理方式二:通過分步查詢--><resultMap id="empDeptMapStep" type="EmpDept"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /><result property="deptId" column="dept_id" /><!--select :設置分布查詢的Sql的唯一標識(namespace.SQLId或mapper接口的全類名.方法名)column :設置分布查詢的條件fetchType: 延遲加載 ,只有當全局配置lazyLoadingEnabled設置為true時,fetchType=lazy才會延遲加載,否則都是立即加載fetchType="eager|lazy" eager:立即加載; lazy:延遲加載 且此處設置的優先級高于全局配置--><association property="dept"select="com.giser.mapper.DeptMapper.selectEmpAndDeptByStepTwo"column="dept_id"fetchType="lazy"></association></resultMap>
3.2 一對多映射
3.2.1 使用collection實現一對多映射
存在如下實體:
public class DeptEmp {private Integer id;private String deptName;private String deptNo;private List<Emp> emps;// getter setter
}
public class Emp {private Integer id;private String userName;private String passWord;private String sex;private Integer deptId;// getter setter
}
/*** 一對多關系查詢* @param deptId* @return*/
DeptEmp selectDeptAndEmpByDeptId(@Param("deptId")Integer deptId);
<resultMap id="deptAndEmpResultMap" type="DeptEmp"><id property="id" column="id" /><result property="deptName" column="dept_name" /><result property="deptNo" column="dept_no" /><!--collection : 處理一對多關系映射property: 集合屬性字段名稱ofType : 表示該集合中存儲的數據類型--><collection property="emps" ofType="Emp"><id property="id" column="id" /><result property="userName" column="user_name" /><result property="passWord" column="pass_word" /><result property="sex" column="sex" /></collection>
</resultMap><select id="selectDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">select * from t_dept left join t_emp on t_dept.id = t_emp.dept_id where t_dept.id = #{deptId}
</select>
3.2.2 使用分步查詢實現一對多映射
DeptEmp selectDeptAndEmpByStepOne(@Param("deptId")Integer deptId);
<resultMap id="selectDeptAndEmpByStepResultMap" type="DeptEmp"><id property="id" column="id" /><result property="deptName" column="dept_name" /><result property="deptNo" column="dept_no" /><collection property="emps"
select="com.giser.mapper.EmpMapper.selectDeptAndEmpByStepTwo"column="id"></collection>
</resultMap><select id="selectDeptAndEmpByStepOne" resultMap="selectDeptAndEmpByStepResultMap">select * from t_dept where id = #{deptId}
</select>
Emp selectDeptAndEmpByStepTwo(@Param("deptId")Integer deptId);
<select id="selectDeptAndEmpByStepTwo" resultType="Emp">select * from t_emp where dept_id = #{deptId}
</select>