自定义映射resultMap
2026/1/15大约 3 分钟MyBatisresultMap关联映射
自定义映射resultMap
1. 处理字段和属性的映射关系
若字段名和实体类中的属性名不一致,则可以通过 resultMap 设置自定义映射。
解决方案
若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用 _),实体类中的属性名符合 Java 的规则(使用驼峰),此时可通过以下三种方式处理:
方式一:为字段起别名
<select id="getEmpByEmpId" resultType="Emp">
select emp_id empId, emp_name empName, age, sex, email from t_emp where emp_id = #{empId}
</select>方式二:设置全局配置
在 MyBatis 的核心配置文件中设置全局配置信息 mapUnderscoreToCamelCase:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>设置后,字段名 user_name 会自动转换为 userName。
方式三:使用 resultMap
<resultMap id="empResultMap" type="Emp">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
</resultMap>
<select id="getEmpByEmpId" resultMap="empResultMap">
select * from t_emp where emp_id = #{empId}
</select>resultMap 标签说明
id:设置主键的映射关系result:设置普通字段的映射关系property:设置映射关系中实体类中的属性名column:设置映射关系中表中的字段名
2. 多对一映射处理
查询员工信息以及员工所对应的部门信息。
方式一:级联方式处理映射关系
<resultMap id="empAndDeptResultMapOne" type="Emp">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<result property="dept.deptId" column="dept_id"/>
<result property="dept.deptName" column="dept_name"/>
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
select * from t_emp e left join t_dept d on e.dept_id = d.dept_id where e.emp_id = #{empId}
</select>方式二:使用 association 处理映射关系
<resultMap id="empAndDeptResultMapTwo" type="Emp">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<association property="dept" javaType="Dept">
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
</association>
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
select * from t_emp e left join t_dept d on e.dept_id = d.dept_id where e.emp_id = #{empId}
</select>方式三:分步查询
第一步:查询员工信息
<!-- EmpMapper.xml -->
<resultMap id="empAndDeptByStepResultMap" type="Emp">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
<association property="dept"
select="com.example.mapper.DeptMapper.getDeptByDeptId"
column="dept_id"/>
</resultMap>
<select id="getEmpAndDeptByStep" resultMap="empAndDeptByStepResultMap">
select * from t_emp where emp_id = #{empId}
</select>第二步:根据部门 id 查询部门信息
<!-- DeptMapper.xml -->
<select id="getDeptByDeptId" resultType="Dept">
select * from t_dept where dept_id = #{deptId}
</select>3. 一对多映射处理
方式一:使用 collection
<resultMap id="deptAndEmpResultMap" type="Dept">
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
<collection property="emps" ofType="Emp">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
<result property="age" column="age"/>
<result property="sex" column="sex"/>
<result property="email" column="email"/>
</collection>
</resultMap>
<select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
select * from t_dept d left join t_emp e on d.dept_id = e.dept_id where d.dept_id = #{deptId}
</select>方式二:分步查询
第一步:查询部门信息
<!-- DeptMapper.xml -->
<resultMap id="deptAndEmpByStepResultMap" type="Dept">
<id property="deptId" column="dept_id"/>
<result property="deptName" column="dept_name"/>
<collection property="emps"
select="com.example.mapper.EmpMapper.getEmpByDeptId"
column="dept_id"/>
</resultMap>
<select id="getDeptAndEmpByStep" resultMap="deptAndEmpByStepResultMap">
select * from t_dept where dept_id = #{deptId}
</select>第二步:根据部门 id 查询员工信息
<!-- EmpMapper.xml -->
<select id="getEmpByDeptId" resultType="Emp">
select * from t_emp where dept_id = #{deptId}
</select>4. 延迟加载
分步查询的优点:可以实现延迟加载。
全局配置
<settings>
<!-- 延迟加载的全局开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>- lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
- aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载
局部配置
可通过 association 和 collection 中的 fetchType 属性设置当前的分步查询是否使用延迟加载:
fetchType="lazy":延迟加载fetchType="eager":立即加载
<association property="dept"
select="com.example.mapper.DeptMapper.getDeptByDeptId"
column="dept_id"
fetchType="lazy"/>