本文为 SSM 框架系列之 MyBatis 第八部分:ResultMap 的结果集映射
其它内容的链接如下:
【1】MyBatis01:初识 MyBatis 与 第一个 MyBaits 程序
【2】MyBatis02:CRUD 操作
【3】MyBatis03:配置解析
【4】MyBatis04:作用域和生命周期
【5】MyBatis05:分页
【6】MyBatis06:日志
【7】MyBatis07:使用注解开发
【8】MyBatis08:ResultMap 的结果集映射
【9】MyBatis09:动态 SQL 与缓存

传送门:

  • 1 ResultMap 的结果集映射
    • 1.1 ResultMap 的使用
    • 1.2 多对一的处理
      • 1.2.1 需求
      • 1.2.2 建表
      • 1.2.3 建立实体类
      • 1.2.4 编写对应的 Mapper 接口
      • 1.2.5 编写对应的 Mapper.xml 文件
      • 1.2.6 在 MyBatis 配置文件中绑定对应的 Mapper 接口
      • 1.2.7 利用 ResultMap 实现需求
      • 1.2.8 编写测试类测试
    • 1.3 一对多的处理
      • 1.3.1 需求
      • 1.3.2 SQL 语句
      • 1.3.3 建立实体类
      • 1.3.4 编写对应的 Mapper 接口
      • 1.3.5 编写对应的 Mapper.xml 文件
      • 1.3.6 在 MyBatis 配置文件中绑定对应的 Mapper 接口
      • 1.3.7 利用 ResultMap 实现需求
      • 1.3.8 编写测试类测试
    • 1.4 总结

1 ResultMap 的结果集映射

1.1 ResultMap 的使用

在 xml 中有两个结果集,一个是 resultType,另一个是 resultMap。前者表示的是具体类型的结果,后者则是将结果集映射。

还记得在 JavaWeb 中,自己老是不能将某一个字段的值注入到 JavaBean 中吗?原因就是这两者的名称不同,而 ResultMap 就实现了即使两者名称不同,依旧可以将数据库中的值注入到 JavaBean 中。

示例:数据库中 User 表中密码的字段是 password,而对应的 JavaBean 的变量名是 pwd,这个时候,是不能表中的值注入到 JavaBean 中的。

解决方法为

<resultMap id="UserMap" type="User"><!-- property 表示实体类的属性,column 表示数据库中的字段--><result property="pwd" column="password"/>
</resultMap><select id="selectUser" resultMap="UserMap">select * from mybatis.user
</select>

其中,resultMap 中的属性是单一属性,所以比较好理解,接下来,将详细说明该属性是一个对象的情况。

1.2 多对一的处理

1.2.1 需求

有两张表,其中一张是学生表,另一张是老师表,其中多个学生对应一个老师,现在想查询所有学生及对应老师的信息

即如下结果:

1.2.2 建表

利用 SQL 语句建立如上的两张表用来测试:

CREATE TABLE `teacher` (`id` INT(10) NOT NULL,`name` VARCHAR(30) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO teacher(`id`, `name`) VALUES (1, '赵老师');CREATE TABLE `student` (`id` INT(10) NOT NULL,`name` VARCHAR(30) DEFAULT NULL,`tid` INT(10) DEFAULT NULL,PRIMARY KEY (`id`),FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', 'Sharm', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', 'Luma', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', 'Lilei', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', 'Noma', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', 'Yiha', '1');

此时,如果想得到需求的结果,是可以直接用 SQL 语句得到的,如:

select s.id , s.name student_name, t.name teacher_name
from student s, teacher t
where s.tid = t.id;

但要想清楚,怎么使用 MyBatis 得到如上结果?继续看下去吧。

1.2.3 建立实体类

在实际工作中,无论有没有需求,都应该写上,以备后来之需

下面的实体类我只书写属性部分,因为后面的 getter、setter 等方法都是相同的。

1)Teacher 实体类

public class Teacher {private int id;private String name;}

2)Student 实体类

public class Student {private int id;private String name;private Teacher teacher;}

1.2.4 编写对应的 Mapper 接口

package sharm.dao;import sharm.pojo.Student;import java.util.List;public interface StudentsMapper {List<Student> selectStudents();
}

1.2.5 编写对应的 Mapper.xml 文件

为了便于阅读,我们在 main 文件夹中存放接口,在 resource 文件夹中存放 xml 文件,在编译后,会发现两者是在同一个文件下的。

代码内容见本章 9.2.7 小节。

1.2.6 在 MyBatis 配置文件中绑定对应的 Mapper 接口

    <!--主程序中每一个 mapper.xml都必须写一个,否则会报错--><mappers><mapper resource="sharm/dao/StudentsMapper.xml"/></mappers>

1.2.7 利用 ResultMap 实现需求

1)按照结果进行嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace = 绑定一个对应的 Dao/Mapper 接口。这很重要,不能写错。-->
<mapper namespace="sharm.dao.StudentsMapper"><!-- 按结果嵌套处理 --><select id="selectStudents" resultMap="StudentTeacher" >select s.id sid, s.name sname , t.name tnamefrom student s,teacher twhere s.tid = t.id</select><resultMap id="StudentTeacher" type="Student"><result property="id" column="sid"/><result property="name" column="sname"/><!--关联对象property 关联对象在Student实体类中的属性--><association property="teacher" javaType="Teacher"><result property="name" column="tname"/></association></resultMap>
</mapper>

2)按照查询进行嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace = 绑定一个对应的 Dao/Mapper 接口。这很重要,不能写错。-->
<mapper namespace="sharm.dao.StudentsMapper"><select id="selectStudents" resultMap="StudentTeacher">select * from mybatis.student</select><resultMap id="StudentTeacher" type="Student"><!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名--><association property="teacher"  column="tid" javaType="Teacher" select="selectTeacher"/></resultMap><select id="selectTeacher" resultType="Teacher">select * from mybatis.teacher where id = #{tid}</select>
</mapper>

1.2.8 编写测试类测试

@Test
public void testSelectStudents(){SqlSession sqlSession = MyBatisUtils.getSession();StudentsMapper mapper = sqlSession.getMapper(StudentsMapper.class);List<Student> students = mapper.selectStudents();for (Student student: students) {System.out.println(student);}sqlSession.close();
}

1.3 一对多的处理

1.3.1 需求

有两张表,其中一张是学生表,另一张是老师表,其中一个老师对应多个学生,现在想查询一个老师及对应所有学生的信息

1.3.2 SQL 语句

此时,如果想得到需求的结果,是可以直接用 SQL 语句得到的,如:

select s.id sid, s.name sname , t.name tname, t.id tid
from student s,teacher t
where s.tid = t.id and t.id= 1;

但该怎么使用 MyBatis 得到如上结果呢?继续看下去吧。

1.3.3 建立实体类

1)Teacher 实体类

public class Teacher {private int id;private String name;private List<Student> Students;}

2)Student 实体类

public class Student {private int id;private String name;// 对应老师的 ID 号private int tid;}

1.3.4 编写对应的 Mapper 接口

package sharm.dao;import sharm.pojo.Teacher;public interface TeacherMapper {public Teacher selectTeacher(int id);
}

1.3.5 编写对应的 Mapper.xml 文件

为了便于阅读,我们在 main 文件夹中存放接口,在 resource 文件夹中存放 xml 文件,在编译后,会发现两者是在同一个文件下的。

代码内容见本章 9.3.7 小节。

1.3.6 在 MyBatis 配置文件中绑定对应的 Mapper 接口

<mappers><mapper resource="sharm/dao/TeacherMapper.xml"/>
</mappers>

1.3.7 利用 ResultMap 实现需求

1)按照结果进行嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="sharm.dao.TeacherMapper">
<!--
思路:1. 集合的话,使用 collection;2. JavaType 和 ofType 都是用来指定对象类型的;其中,JavaType 是用来指定 pojo 中属性的类型;ofType 指定的是映射到 list 集合属性中 pojo 的类型。
-->
<select id="selectTeacher" resultMap="TeacherStudent">select s.id sid, s.name sname , t.name tname, t.id tidfrom student s,teacher twhere s.tid = t.id and t.id=#{id}
</select><resultMap id="TeacherStudent" type="Teacher"><result  property="name" column="tname"/><collection property="students" ofType="Student"><result property="id" column="sid" /><result property="name" column="sname" /><result property="tid" column="tid" /></collection>
</resultMap>
</mapper>

2)按照查询进行嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="sharm.dao.TeacherMapper"><select id="selectTeacher" resultMap="TeacherStudent">select * from teacher where id = #{id}</select><resultMap id="TeacherStudent" type="Teacher"><!--column是一对多的外键 , 写的是一的主键的列名--><collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/></resultMap><select id="getStudentByTeacherId" resultType="Student">select * from student where tid = #{id}</select>
</mapper>

1.3.8 编写测试类测试

@Test
public void testSelectTeacher(){SqlSession sqlSession = MyBatisUtils.getSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher = mapper.selectTeacher(1);System.out.println(teacher);sqlSession.close();
}

1.4 总结

  1. 多对一,即多个学生关联一个老师,在 MyBatis 中叫做关联(association);
  2. 一对多,即一个老师包含多个学生,在 MyBatis 中叫做集合(collection);
  3. 在实际工作中,要多向优秀的人学习他们的代码;
  4. 保证SQL的可读性,尽量通俗易懂。同时根据实际要求,尽量编写性能更高的SQL语句。

MyBatis08:ResultMap 的结果集映射相关推荐

  1. MyBatis08:ResultMap 的结果集映射,java编程题面试题

    1.2.7 利用 ResultMap 实现需求 1.2.8 编写测试类测试 1.3 一对多的处理 1.3.1 需求 1.3.2 SQL 语句 1.3.3 建立实体类 1.3.4 编写对应的 Mappe ...

  2. MyBatis08:ResultMap 的结果集映射,面试官问的那些Java原理你都懂吗

    1 ResultMap 的结果集映射 1.1 ResultMap 的使用 1.2 多对一的处理 1.2.1 需求 1.2.2 建表 1.2.3 建立实体类 1.2.4 编写对应的 Mapper 接口 ...

  3. MyBatis魔法堂:ResultMap详解

    一.前言   MyBatis是基于"数据库结构不可控"的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与 ...

  4. [mybatis]select_resultMap_自定义结果集映射规则

    resultMap 自定义某个javaBean的封装规则 type:自定义规则的Java类型 id:唯一id方便引用 指定主键列的封装规则 id:定义主键底层会有优化 column:指定哪一列 pro ...

  5. JavaEE——Mybatis(5)--resultMap自定义结果集封装

    <!--自定义某个javaBean的封装规则type:自定义规则的Java类型id:唯一id方便引用--><resultMap type="com.atguigu.myba ...

  6. ResultMap详解

    前言 MyBatis是基于"数据库结构不可控"的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转 ...

  7. ResultMap的使用

    前言 MyBatis是基于"数据库结构不可控"的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBatis为我们提供这种理想与现实间转 ...

  8. MyBatis07:使用注解开发

    本文为 SSM 框架系列之 MyBatis 第七部分:使用注解开发 其它内容的链接如下: [1]MyBatis01:初识 MyBatis 与 第一个 MyBaits 程序 [2]MyBatis02:C ...

  9. MyBatis02:CRUD 操作

    本文为 SSM 框架系列之 MyBatis 第二部分:增删改查操作 其它内容的链接如下: [1]MyBatis01:初识 MyBatis 与 第一个 MyBaits 程序 [2]MyBatis02:C ...

最新文章

  1. MYSQL查询空值/NULL值
  2. 【渝粤教育】国家开放大学2018年春季 0004-22T有机合成单元反应 参考试题
  3. python异常和错误(syntax errors 和 exceptions)
  4. Deep Learning for NLP Best Practices
  5. 容器技术Docker K8s 43 Serverless Kubernetes(ASK)详解-ASK网络、存储、日志、监控管理
  6. Delphi教程推荐
  7. 揭秘百度新治理结构:马东敏的谣言与李彦宏的用人观
  8. libvlc 裁剪及编译
  9. layui的layer弹出层内置方法
  10. win 10 硬盘安装 ubuntu 18.04
  11. 设计模式---外观(Facade)模式
  12. 手游测试常见10个坑及填坑建议
  13. 数据结构整理笔记(提纲) (数据结构 C语言版 第二版 严蔚敏)
  14. springboot+cas单点登录
  15. CentOS8(8.2)安装mysql8
  16. Android CardView卡片布局详解(八)
  17. 无线网络技术——星链——三两问
  18. 什么是算法?算法的5个特性
  19. 微信小程序中使用slot插槽
  20. 红酒泡洋葱喝了有什么好处

热门文章

  1. 网工内推 | 互联网大厂,字节跳动招资深网工,最高40k*15薪
  2. AI4DB:人工智能之慢SQL根因分析
  3. python线程池抓取网页数据
  4. 得物 API 一站式协作平台探索与落地
  5. 两步完成ubuntu18.04 下安装腾讯官网提供的QQ for linux
  6. OTP 动态口令验证
  7. Android中的应用!!!!
  8. Qt6 正式发布了,这将是一个里程碑式新版本,它的使命是使 Qt 成为未来的开发平台。
  9. (附源码)计算机毕业设计ssm电影院订票系统
  10. E- prime数据收集后的整理部分