Mybatis的resultMap和分步查询

本文详细介绍了在MyBatis中如何使用级联查询来获取关联表的数据,包括自定义封装规则、利用association属性进行对象赋值,以及分步查询的方法。同时,探讨了如何通过配置实现延迟加载,提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当数据可以表项名与javaBean的属性不对应的时候,要是符合驼峰命名法可以在全局配置文件开启驼峰命名法的对应关系例如(数据库:last_name,JavaBean : lastName),此外可以查询是进行重命名。

但是resultMap可以自己设置封装规则。如下
在这里插入图片描述
在这里插入图片描述
他的另一个作用就是进行级联查询
进行级联查询:通过id查员工以及所在部门,(部门是外键)
employee 表
在这里插入图片描述
部门表
在这里插入图片描述
想要执行的查询的语句。

select e.id as id,e.last_name as  last_name,e.email as email,e.gender as gender ,
            e.d_id as d_id,d.dept_name as dept_name from dept as d,employee as e where d.id=e.d_id and e.id=5;

在这里插入图片描述

javaBean如下:
在这里插入图片描述
在这里插入图片描述
级联查询赋值时,按照类访问属性的方式进行赋值,
注意:column属性的值是sql语句查询出来的语句。并且id要放在第一位,不然报错。
在这里插入图片描述
级联查询的另一种引用对象赋值方法:

利用association属性进行查询,
<association>属性就是子对象赋值,property是在emloyee类中,哪一个属性是引用类型,javaType是此属性对应的类,然后进行赋值。

在这里插入图片描述


级联查询之分步查询


还是employee和department类两个,属性如下:

public class Department
 {
	private  Integer id;
	private  String dept_name;
  }

public class Employee
{
private Integer id;
private String lastName;
private  String email;
private  String gender;
private  Department department;
 }

EmployeeMapper和DepartmentMapper接口

public interface EmployeeMapperPlus {
    public Employee getEmpANndDeptByIdStep(Integer id);
}
public interface DepartmentMapper {
    public Department getDepById(int id);
}

EmployeeMapper.xmlr和DepartmentMapper.xml接口


***employeeMapper***:

   <resultMap id="myMapStep" type="test.Employee">
        <!--   用id和result都可以封装 id定义主键(底部有优化) result封装普通类 -->
        <id column="id" property="id"></id>
        <result column="last_name" property="lastName"></result>
        <result column="email" property="email"></result>
        <result column="gender" property="gender"></result>
        <association property="department" select="com.company.DepartmentMapper.getDepById" column="d_id"></association>
    </resultMap>
    <select id="getEmpANndDeptByIdStep" resultMap="myMapStep">
        select * from employee where id = #{id}
    </select>
    
  ***DepartmentMapper.xml***:
  
<mapper namespace="com.company.DepartmentMapper">
    <select id="getDepById" resultType="test.Department">
        select id,dept_name from dept where id = #{id}
    </select>
</mapper>

在这里插入图片描述
在这里插入图片描述
延迟加载:
像上面的级联查询,只要在需要查询员工的Department时才查询级联的查询,否则只需要查询第一步查询,而不需要查询department。

例如 :         
Employee employee = mapper.getEmpANndDeptByIdStep(5);
System.out.println(employee.getLastName());
只查询第一步,而不查询department。
只需要在全局配置文件里加上如下设置。
    <settings>
        <setting name="aggressiveLazyLoading" value="false"/>
        <setting name="lazyLoadingEnable" value="true"/>
    </settings>
<think>首先,用户的问题是关于MyBatis ResultMap的自动去重配置方法。用户意图是希望在使用ResultMap时实现自动去重功能,避免查询结果中重复记录的映射问题。 回顾系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐解决问题,尽量保证回答真实可靠。 参考的引用内容: - 引用[1]:解释了MyBatis ResultMap默认去重的原因,即基于id主键去重。 - 引用[2]:提到了ResultMapResultType的区别,ResultMap更强大。 - 引用[3]:关于MyBatis配置的笔记,如cacheEnabled。 - 引用[4]:强调了associationcollection中的id属性用于去重。 - 引用[5]:日志设置相关。 用户的问题焦点是“自动去重配置方法”,所以我需要基于这些引用构建一个清晰的回答。 关键点: - MyBatis ResultMap默认使用id属性作为主键来去重。当id相同时,视为相同记录,去重。 - 如果查询结果中有重复记录(如JOIN导致),可以通过正确配置id属性来避免重复。 - 在associationcollection中,id属性是可选的,但建议添加以支持去重。 回答结构: 1. **解释默认行为**:简述MyBatis ResultMap如何默认去重。 2. **配置去重方法**:详细说明如何配置ResultMap来实现自动去重。 3. **示例代码**:提供ResultMap配置的代码示例。 4. **注意事项**:提到可能的陷阱优化。 5. **生成相关问题**:在末尾添加相关问题。 确保使用中文回答。 生成相关问题: - 基于主题,如性能、优化、应用场景等。 - 例如: 1. 如何避免MyBatis查询结果重复? 2. ResultMap中associationcollection的配置技巧? 3. MyBatis去重机制的原理是什么? 在回答中,引用相关段落时添加标识。例如,提到引用[1]的解释时加[^1]。 最终回答框架: - 开头:直接回答问题。 - 主体:分步解释。 - 结尾:相关问题。</think>### MyBatis ResultMap 自动去重配置方法 MyBatisResultMap 默认使用 `id` 属性作为主键来映射查询结果。当查询结果中存在重复的 `id` 值时,MyBatis 会自动去重,只保留一条记录,避免重复映射[^1]。这在处理 JOIN 查询时尤其常见,因为 JOIN 可能导致相同主键的记录重复出现。以下是实现自动去重的详细配置方法: #### 骤 1: 理解默认去重机制 - **原理**:ResultMap 将 `<id>` 标签定义的属性作为主键。如果多条记录的 `id` 值相同,MyBatis 会视为同一对象并进行去重[^1]。 - **适用场景**:适用于查询中包含多表 JOIN 的情况,例如: ```sql SELECT app_info.*, dic.valueName AS flatformName FROM app_info JOIN data_dictionary dic ON dic.valueId = app_info.flatformId ``` 如果 `app_info.id` 重复,MyBatis 会自动去重[^1]。 #### 骤 2: 配置 ResultMap 实现自动去重 在 MyBatis 的映射文件(如 `mapper.xml`)中,通过 `<resultMap>` 标签定义主键(`<id>`)普通字段(`<result>`)。确保 `<id>` 属性正确对应数据库主键列: ```xml <resultMap id="appInfoMap" type="com.example.AppInfo"> <!-- 定义 id 属性作为主键,用于自动去重 --> <id property="id" column="id"/> <!-- property 是实体类属性,column 是查询结果列名 --> <result property="name" column="app_name"/> <!-- 关联对象时,在 association 或 collection 中也添加 id 属性 --> <association property="flatform" javaType="com.example.Flatform"> <id property="flatformId" column="flatformId"/> <!-- 子对象的 id 用于去重 --> <result property="flatformName" column="flatformName"/> </association> </resultMap> ``` - **关键点**: - **必须定义 `<id>` 属性**:这是去重的核心。如果省略 `<id>`,MyBatis 无法识别主键,可能导致重复记录[^4]。 - **在关联对象中使用 id**:对于嵌套对象(如 `association` 或 `collection`),添加 `<id>` 属性可避免子对象重复[^4]。 - **确保列名唯一**:查询 SQL 中,主键列(如 `id`)必须无歧义。如果多表有相同列名,使用别名(如 `app_info.id AS app_id`)。 #### 骤 3: 处理查询 SQL 在查询语句中,确保主键列在结果集中唯一: ```sql SELECT app_info.id AS id, -- 显式指定主键别名 app_info.app_name, dic.valueName AS flatformName FROM app_info JOIN data_dictionary dic ON dic.valueId = app_info.flatformId ``` - **避免列冲突**:如果多表有相同列名(如多个 `id`),必须使用别名区分,否则 MyBatis 可能无法正确去重[^1]。 #### 注意事项 1. **性能影响**:去重基于内存映射,大数据量时可能影响性能。建议通过 SQL 优化减少重复数据(如使用 `DISTINCT` 或调整 JOIN 逻辑)[^1][^4]。 2. **日志调试**:启用 MyBatis 日志(在 `log4j.properties` 中设置 `log4j.logger.org.mybatis=DEBUG`),检查映射过程是否触发去重[^5]。 3. **常见错误**: - 未定义 `<id>` 属性:导致所有记录被视为不同,不去重。 - 主键列不唯一:如 JOIN 后 `id` 重复,但期望保留多条记录时,需通过 SQL 解决(如添加行号)。 通过以上配置,MyBatis 会自动基于 `id` 去重,无需额外插件或代码[^1][^4]。如果问题复杂(如多层嵌套集合),可结合数据库层去重(如 `GROUP BY`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值