一。字段映射
比如有张数据表结构如下:

在后台的JavaBean中,如果遵守规范的话,属性名和列名一致,那么我们就不需要手动做字段映射,MyBatis会自动帮我们把值填充到Bean中。但现在情况不一样,Bean的属性名和数据库列名对应不上。
import java.util.ArrayList;
 
import java.util.List;
 
public class Grade {
 
    private String gradeId;        // 班级ID
    private String gName;        // 班级名
    private List<Student> stuList = new ArrayList<Student>(); // 班级中的学生
 
    public String getGradeId() {
            return gradeId;
    }
 
 
    public void setGradeId(String gradeId) {
            this.gradeId = gradeId;
    }
 
 
    public String getgName() {
            return gName;
    }
 
 
    public void setgName(String gName) {
            this.gName = gName;
    }
 
 
    public List<Student> getStuList() {
            return stuList;
    }
 
 
    public void setStuList(List<Student> stuList) {
            this.stuList = stuList;
    }
 
    @Override
    public String toString() {
            return "Grade [gradeId=" + gradeId + ", gName=" + gName + ", stuList="
                            + stuList + "]";
    }
}
gradeId和GID明显对应不上,但是修改列或者属性名是不可取的,原因不多说。我们可以通过MyBatis的字段映射在不修改代码的情况下完成这个需求,给它俩建立一种映射关系:
字段映射,当数据库的列名和类的属性名不一致时,需要通过建立映射关系使得它俩对应上。

返回的结果都是grade(自己取的typeAliases),只是多了一层映射关系。

<resultMap type="grade" id="mappingGid">
        <!-- 主键列用id标签 -->
        <id property="gradeId" column="GID"/>
<!--                 
        非主键就用result:                
        <result property="gName" column="gname"/>         -
->
</resultMap>
<select id="queryAll" resultType="grade" resultMap="mappingGid">
        select * from grade
</select>
 restltMap属性指向上边定义的resultMap的id即可。resultMap标签还有个autoMapping属性,意思是自动映射,默认值是true,改成false的话就要手动指定需要建立映射关系的列以及属性了。

二。多对一(many to one) 映射

表关系:

grade表:GID、GNAME
student表:SID、SNAME、GID
GID是关联grade表的外键。

多对一的视角:student --> grade。多个学生对应一个grade,一个学生只能有一个grade。

在设计Bean的时候,应该是这样的:
public class Student {
 
 
    private String sId;
    private String sName;
    private Grade grade;
 
 
    public String getsId() {
            return sId;
    }
 
 
    public void setsId(String sId) {
            this.sId = sId;
    }
 
 
    public String getsName() {
            return sName;
    }
 
 
    public void setsName(String sName) {
            this.sName = sName;
    }
 
    public Grade getGrade() {
            return grade;
    }
 
 
    public void setGrade(Grade grade) {
 
            this.grade = grade;
 
    }
 
 
    @Override
    public String toString() {
            return "Student [sId=" + sId + ", sName=" + sName + ", grade=" + grade
                            + "]";
    }
 
}
包含一个grade属性,在查询到学生信息的同时把对应的班级查出来并填充进去。当然用Java代码编写逻辑也是完全能够实现的,但是有了MyBatis的结果集映射,我们并不需要编写这样的逻辑。确定好是一对多关系后,在映射文件中声明映射关系。下面就把这个例子的代码都贴上来吧:

Student映射接口:
import java.util.List;
import cn.et.lesson03.entity.Student;
public interface StudentMapper {
    <!-- 映射多对一关系 -->
 
    <resultMap type="student" id="mappingGrade">
 
            <association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
 
    </resultMap>

/* 根据ID查询学生 */ public Student queryStuById(String sId); /*根据班级ID查询学生*/ public List<Student> queryStusByGId(String gId);}
现在要调用queryStuById,返回一个student的同时,把这个student的grade属性填充进去,也就是说还需要一个 select * from grade where gid = x 这么一条SQL语句,定义在grade类对应的映射文件中:

<select id="queryGradeByGid" resultType="grade">
 
            select * from grade where GID = #{gid}
 
    </select>
然后在Student类的映射文件中建立映射关系:
    <!-- 映射多对一关系 -->
 
    <resultMap type="student" id="mappingGrade">
 
            <association property="grade" column="gid" select="cn.et.lesson03.xml.GradeMapper.queryGradeByGid"></association>
 
    </resultMap>
 type = 查询返回结果
 id = 映射命名
association = 声明是多对一映射。
property="grade" 需要填充的属性
column="gid" 外键列
select= 获取对应的grade数据行的SQL语句,上上边那个,语法格式:命名空间.声明。

映射接口中方法的SQL语句:
    <select id="queryStuById" resultType="student" resultMap="mappingGrade">
 
            select * from student where SID = #{0}
 
    </select>
 测试方法:
@Test
 
    public void mappingGrade() throws IOException{
 
            SqlSession session = getSession();
            StudentMapper mapper = session.getMapper(StudentMapper.class);
            Student student = mapper.queryStuById("1");
            System.out.println(student.getGrade());
}
结果:

流程:
    调用方法 --> 执行接口映射方法之前先执行resultMap --> 
    通过association中的column外键,执行association对应的SQL语句获取结果集,填充到
    property --> resultMap结束 --> 执行方法对应的SQL语句返回最终结果。

三。一对多映射(one to many)

一对多映射很简单,一个班级对应多个学生,查询一个班级的同时获取班级中的所有学生,填充到stuList属性中:

把上面的例子反过来想就OK了。班级和学生在数据库中的关系是主外键关联,通过grade表的主键到student表查询,需要一个这个的语句:select * from student where GID = #{gid}。

这个语句在Student的映射文件中定义:
    <select id="queryStusByGId" resultType="student">
 
            select * from student where GID = #{gid}
 
    </select>

然后在Grade的映射文件中,定义结果集映射:
    <resultMap type="grade" id="mappingStuList">
 
            <collection property="stuList" javaType="arraylist" column="gid" select="cn.et.lesson03.xml.StudentMapper.queryStusByGId"></collection>
 
    </resultMap>
一对多关系用collection表示。
property = 要填充的属性
javaType = 该属性的数据类型
column = 主键,studen表的外键
select = student映射文件中的语句: select * from student where GID = #{gid}

测试方法:
    @Testpublic void queryStu() throws IOException {
 
            SqlSession session = getSession();
 
            GradeMapper mapper = session.getMapper(GradeMapper.class);
 
            Grade grade = mapper.queryGradeById("1");
 
            
 
            List<Student> list = grade.getStuList();
 
            for (Student student : list) {
 
                    System.out.println(student.getsId() + "---" + student.getsName());
 
            }
 
    }

运行结果:

四。基于注解实现的结果集映射

字段映射:
    @Results({
 
    @Result(column="SID" , property = "stuId" , id = true)})
 
    @Select("select * from student where sid = #{sId}")
 
    public Student queryStuById(String sId);
多对一映射:
    @Results({
 
                    @Result(column = "SID", property = "stuId", id = true),
 
                    @Result(property = "grade", column = "GID", 
 
                    one = @One(select = "cn.et.lesson03.anno.GradeMapper.queryGradeById")) })
 
    @Select("select * from student where sid = #{sId}")
 
    public Student queryStuById(@Param("sId") String sId);
one表示多对一映射,多个学生属于一个grade,指向的方法也是一个grade:
 @Select("select * from grade where GID = #{0}")
 
    public Grade queryGradeById(String gId);
一对多映射:
指向的方法返回值是个list,所以还要在映射声明中指定一下javaType。
   
@Results({ 
    @Result(column = "GID", property = "stuList", javaType = ArrayList.class, 
     many = @Many(select = "cn.et.lesson03.anno.StudentMapper.queryStusByGId")) })
 
    @Select("select * from grade where GID = #{0}")
 
    public Grade queryGradeById(String gId);
一对多用many表示,因为查询结果是多条,指向方法:
    @Results({
 
    @Result(column = "SID" , property = "stuId")})
 
    @Select("select * from student where GID = #{param1}")
 
    public List<Student> queryStusByGId(String gId);

MyBatis -- 结果集映射相关推荐

  1. Mybatis结果集映射

    一.使用场景 当数据库里的列名和实体类的属性名不一致,就需要进行结果映射 二.UserMapper接口 package com.william.dao;import com.william.domai ...

  2. 一文彻底读懂优秀开源产品MyBatis一级缓存设计!

    孙玄 奈学教育CEO 读完需要 3 分钟 速读仅需 1 分钟 孙玄, 现任奈学教育科技创始人&CEO ,毕业于浙大,前百度资深研发工程师.前 58 集团技术委员会主席/高级系统架构师到前转转公 ...

  3. Mybatis为什么查询结果为空时返回值为NULL或空集合?

    以下内容如有错误欢迎指出,有则改之无则加勉~ 一行数据记录如何映射成一个 Java 对象,这种映射机制是 MyBatis 作为 ORM 框架的核心功能之一,也是我们这篇文章需要学习的内容 开始前我们先 ...

  4. mybatis多对一映射association详解

    简单映射(一对一) 多对一映射 方式1:按照查询嵌套处理 方式2:按照结果嵌套处理 简单映射(一对一) mybatis结果集映射ResultMap 多对一映射 我们有2个类,一个班级类ClassRoo ...

  5. mybatis学习2之ResultMap结果集映射

    前言 当实体类的属性和数据库的字段无法对应时我们改怎么办呢? 这里我们一起来学习ResultMap结果映射集 1.ResultMap是什么? resultMap元素用来描述如何将结果集映射到Java对 ...

  6. Mybatis 一对多 结果集映射 简单入门 易懂

    Mybatis官方文档说明处 Mybatis 一对多 结果集映射 简单入门 易懂 一.搭建数据库环境 二.idea 搭建maven 项目 (mybatis-demo) 2.1.项目结构 2.2.导入依 ...

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

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

  8. Mybatis源码阅读(三):结果集映射3.1 —— ResultSetBuilder与简单映射

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如 ...

  9. Java-Mybatis(二): Mybatis配置解析、resultMap结果集映射、日志、分页、注解开发、Mybatis执行流程分析

    Java-Mybatis-02 学习视频:B站 狂神说Java – https://www.bilibili.com/video/BV1NE411Q7Nx 学习资料:mybatis 参考文档 – ht ...

最新文章

  1. java新手笔记1 Hello World!
  2. centos7安装tensorflow_gpu完整教程
  3. SpringBoot2.1+SpringCloud:注册中心搭建(Eureka)
  4. GitHub Pages搭建属于自己的静态网站,并绑定个人域名
  5. 在保护继承中基类的共有成员_C++学习大纲:继承方式的调整
  6. Net Core下使用RabbitMQ比较完备两种方案(虽然代码有点惨淡,不过我会完善)
  7. 解决nginx无法启动的问题——端口被占用
  8. navicat无法连接mysql
  9. 2020年java最新招聘_2021年北京Java 工程师招聘-北京Java 工程师招聘求职信息-拉勾招聘...
  10. javascript绘制静态或者动态的图表、关系表、流程图-JointJS
  11. Atiit 如何手写词法解析器
  12. Ubuntu下 VS code安装并配置C/C++模块
  13. html+css基础教程入门学习之CSS表格
  14. 【ACM】心路历程2019.9.29
  15. redmi Note12T屏幕刷新率是多少 Redmi Note12T相机怎么样 有几个摄像头
  16. 【ZYNQ】中断机制介绍(一)
  17. UKF-协方差矩阵分解
  18. 批量分析中通快运单号物流,并查看是否签收
  19. 测试管理之--团队组建
  20. 如何重新设置苹果id密码_苹果ID密码忘记应该怎么做

热门文章

  1. 双机热备_什么是双机热备?
  2. AT串口抽象层的设计思路及代码实现
  3. java 转发上传文件_Java 发送http请求上传文件功能实例
  4. 64位指针膨胀 java_Java 程序优化知识笔记
  5. 知识图谱学习笔记-风控知识图谱设计
  6. 将单链表的每K个节点之间逆序
  7. 论文笔记 Traffic Data Reconstruction via Adaptive Spatial-Temporal Correlations
  8. 错误处理: pip install 时候 “Read timed out”
  9. 报错整理:ImportError: cannot import name ‘mean_absolute_percentage_error‘ from ‘sklearn.metrics‘
  10. Java高阶部分知识点汇总(一)- 成员变量与局部变量详讲