mapper.xml中的结果映射

本文详细介绍了MyBatis中处理实体间关联关系的方法,包括一对一、一对多等关联映射方式,以及如何通过嵌套结果和嵌套查询实现多表联查,提高数据查询效率。

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

域对象(就是domain下面的类)之间的关联关系:
按照多重性可分为一对一、一对多、多对一和多对多,即数据库中的表之间的关系
根据关联关系,所以以右为主,所以一对一、多对一的处理方式是一样的,一对多和多对多一样,而左边决定抽象方法的返回类型。

举例:一个年级的班级信息表与学生信息表
如果用一张表来存储的话,每条学生数据都有班级字段,并且都是写“xx班级”;
但如果将学生信息和班级信息拆分,而学生表仍有班级Id字段,虽然看起来并没有什么区别,
但是这样就会减少占用的存储空间,毕竟数字肯定是比"xx班级"的字节数小;
一旦数据多了,差距就出现了,而且有利于数据的维护,比如需要改班级信息,两张表的情况下,只需要改班级表就好;但如果在一张表中,需要改与班级相关的每天学生信息。
但两张表的查询要比一张表麻烦一点,
所以就用resultMap来做结果映射:就是在多表查询时,用来根据需求,配置查询结果

============================================================
*对一

员工实体类

public class Employee {

    private Long id;
    private String name;

    //多对一配置:多个员工属于一个部门
    private Department department;

//省略getter与setter,toString
    ...
}

部门实体类

public class Department {
    private Long id;
    private String name;
    //省略getter与setter,toString
    ...
}

映射文件
1、嵌套结果:查出多表的全部字段,然后选自己想要的

<mapper namespace="cn.itsource.many2one.mapper.EmployeeMapper">

    <!--
        resultMap:完成结果映射
            1. id代表映射名称(随便取),给别的sql调用
            2. type:映射对应返回的对象类型
    -->
    <resultMap id="employeeMap" type="cn.itsource.mybatis.many2one.domain.Employee">
        <id property="id" column="id" /><!--id标签表示主键,这里用result也可,但规范一点-->
        <result property="name" column="name" />
        <!--association :联系 -->
        <association property="department" column="dept_id" javaType="cn.itsource.many2one.domain.Department">
            <id  property="id" column="did"/>
            <result property="name" column="dname" />
        </association>
    </resultMap>
    
    <!--
        resultMap:通过id,引用结果映射
            1.把查询结果弄成自己想要的实体类,必需使用结果映射
            2.多张表查询时,如果出现相同的列名,一定要取别名,不然默认赋值出现column值的第一列
    -->
    <select id="findAll" resultMap="employeeMap">
        select e.id,e.name,d.id did,d.name dname from 
        employee e left join department d 
        on d.id = e.dept_id
    </select>

</mapper>

查询结果

2、嵌套查询:先查一张表,然后外键的那一列做为参数,执行另一条sql,去另一张表查
EmployeeMapper.xml

<mapper namespace="cn.itsource.many2one.mapper.EmployeeMapper">

    <resultMap id="employeeMap" type="cn.itsource.many2one.domain.Employee">
        <id property="id" column="id" />
        <result property="name" column="name" />
        
        <!-- select:指向要查询的sql,并执行(如果在同一个文件中可以省略前面的namespace) 
        	 所以xml之间调用sql,是直接根据命名空间+id,而不是去找接口哦~
        	 column:就是把当前查出来的这一列,作为参数,传给select指向的sql-->
        <association property="department" column="dept_id"
                     select="cn.itsource.many2one.mapper.DepartmentMapper.findById">
        </association>
    </resultMap>
    
    <!-- resultMap:引用结果映射 -->
    <select id="findAll" resultMap="employeeMap">
        select * from employee
    </select>

</mapper>

DepartmentMapper.xml:为了规范,操作哪个表的sql就应该写在哪个mapper.xml文件中

<mapper namespace="cn.itsource.many2one.mapper.DepartmentMapper">
    <!--根据id获取相应的部门数据-->
    <select id="findById" resultType="cn.itsource.many2one.domain.Department">
        select * from department where id=#{id}
    </select>
</mapper>

===========================================================
*对多
员工实体类

public class Employee {

    private Long id;
    private String name;
    
	//省略getter与setter,toString
    ...
}

部门实体类

public class Department {
    private Long id;
    private String name;
    //一对多配置(一个部门对应多个员工)
    private List<Employee> employees = new ArrayList<>();
    //省略getter与setter,toString
    ...
}

也是同样的2种处理方式,基本一模一样
而不同点是,联系用的是collectionofType,因为*对多是’多’嘛,当然用集合接收;
而一/多对一,其实也是可以用collection,因为集合能装多个,所以当然能装一个,
不过为了规范,各用各的吧

myBatis会自动把从第二张表查询出来的数据放入对应的list,所以是这样显示的

ClassInfo{id=1, name='0531班级', students=[Student{id=7, name='陈佳星', age=22}, Student{id=8, name='李鹏', age=25}]}
ClassInfo{id=2, name='0532班级', students=[Student{id=9, name='郑杨', age=24}, Student{id=10, name='高小满', age=19}, Student{id=11, name='张鑫', age=21}]}
ClassInfo{id=3, name='0533班级', students=[Student{id=12, name='廖家乐', age=28,}, Student{id=13, name='母杨帆', age=22}]}

### 关于 Mapper.xml 文件中的 SQL 映射配置 #### MyBatis 中的映射文件概述 在 MyBatis 框架内,`Mapper XML` 文件作为核心组件之一,主要用于定义 SQL 语句及其 Java 方法之间的映射关系。这使得开发人员能够轻松地将数据库表结构同应用程序内的实体类关联起来,从而简化了数据访问层的设计和实现过程[^2]。 #### 配置 SQL 映射的基本要素 为了创建有效的 `mapper.xml` 文件,需遵循一定的语法规范: - **命名空间 (namespace)**: 定义该 mapper 对应哪个接口,通常为全限定名。 - **SQL 声明**: 使用 `<select>`, `<insert>`, `<update>` 和 `<delete>` 等标签声明不同类型的 SQL 查询命令,并指定 id 属性以便调用时识别特定查询;resultType 或 resultMap 参数用来指明返回结果的数据类型。 ```xml <mapper namespace="com.example.mapper.UserMapper"> <!-- Select Statement --> <select id="getUserById" resultType="User"> SELECT * FROM users WHERE user_id = #{id} </select> </mapper> ``` 对于更复杂的场景,则可通过自定义的结果映射 (`<resultMap>`) 来处理多对一或多对多的关系等问题。 #### 解决常见问题的方法 ##### 处理参数传递错误 当遇到传入参数不匹配的情况时,检查 SQL 语句中使用的占位符是否正确无误。例如,在上述例子中使用的是 `${}` 还是 `#{}`,前者会直接替换变量而后者则会被视为预编译参数防止注入攻击。 ##### 调试 SQL 执行失败 如果执行过程中出现问题,建议开启日志记录功能查看实际发送给数据库服务器的具体指令。可以在 Spring Boot 的 `application.properties` 文件里添加如下配置项启用 debug 日志级别输出[^1]: ```properties logging.level.com.example.mapper=DEBUG mybatis.configuration.log-impl=STDOUT_LOGGING ``` 这样就可以跟踪到每次操作对应的原始 SQL 文本,便于排查潜在缺陷所在之处。 ##### 移除不必要的样式干扰 有时 IDE 如 IntelliJ IDEA 可能会对 SQL 片段应用默认的颜色编码方案造成视觉上的困扰。对此可调整编辑器设置移除此类效果[^3]: 进入 File -> Settings -> Editor -> Color Scheme -> SQL, 修改或禁用相应的高亮显示选项即可达到目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值