MyBatis笔记(五)

作者: linzeliang
  1. 多对一

什么是多对一呢?

  • 多个学生对应一个老师

    1.1 数据库设计

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`),
    KEY `fktid` (`tid`),
    CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

image-20210412093855997

1.2 搭建测试环境

  1. 编写实体类POJO

    public class Teacher {
       private int id;
       private String name;
    
       // 无参构造
       // 有参构造
       // get、set方法
       // toString方法
    }
    
    ```java
    public class Student {
       private int id;
       private String name;
       //多个学生可以是同一个老师,即多对一
       private Teacher teacher;
    
       // 无参构造
       // 有参构造
       // get、set方法
       // toString方法
    }
    
  2. 编写实体类对应的Mapper接口

    public interface StudentMapper {
    }
    
    ```java
    public interface TeacherMapper {
    }
    
  3. 编写接口对应的mapper.xml配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
           PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="top.linzeliang.mapper.StudentMapper">
    
    </mapper>
    
    ```xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
           PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
           "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="top.linzeliang.mapper.TeacherMapper">
    
    </mapper>
    

    1.3 按查询嵌套处理

  4. 给StudentMapper增加方法

    //获取所有学生及对应老师的信息
    public List<Student> getStudents();
    
  5. 编写对应的Mapper文件

    <!--    需求:获取所有学生及对应老师的信息
           思路:
               1. 获取所有学生的信息
               2. 根据获取的学生信息的老师ID->获取该老师的信息
               3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中们一般使用关联查询?
                   1. 做一个结果集映射:StudentTeacher
                   2. StudentTeacher结果集的类型为 Student
                   3. 学生中老师的属性为teacher,对应数据库中为tid。
                      多个 [1,...)学生关联一个老师=> 一对一,一对多
                   4. 查看官网找到:association -- 一个复杂类型的关联;使用它来处理关联查询
    -->
    <select id="getStudents" resultMap="StudentMap">
       select *
       from student;
    </select>
    <resultMap id="StudentMap" type="student">
       <association property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
    </resultMap>
    
    
    
    <!--
           这里传递过来的id,只有一个属性的时候,下面可以写任何值
           association中column多参数配置:
               column=""
               其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
    -->
    <select id="getTeacher" resultType="Teacher">
       select *
       from teacher
       where id = ;
    </select>
    
  6. 进行测试

    1.4 按结果嵌套处理

个人认为这种容易理解一些

  1. 接口方法编写

    //获取所有学生及对应老师的信息
    public List<Student> getStudents(); 
    
  2. 编写对应的mapper配置文件

    <select id="getStudents" resultMap="StudentMap">
       select t1.id id, t1.name sname, t2.id tid, t2.name tname
       from student t1,
       teacher t2
       where t1.tid = t2.id;
    </select>
    <resultMap id="StudentMap" type="student">
       <id property="id" column="id"/>
       <result property="name" column="sname"/>
       <association property="teacher" javaType="Teacher">
           <id property="id" column="tid"/>
           <result property="name" column="tname"/>
       </association>
    </resultMap>
    
  3. 进行测试

  4. 一对多

  5. 一个老师对应多个学生

    2.1 搭建测试环境

  6. 实体类的编写

    public class Student {
      private int id;
      private String name;
      private int tid;
    
      // 无参构造
      // 有参构造
      // get、set方法
      // toString方法
    }
    
    ```java
    public class Teacher {
      private int id;
      private String name;
      //一个老师多个学生
      private List<Student> students;
    
      // 无参构造
      // 有参构造
      // get、set方法
      // toString方法
    }
    

    2.2 按查询嵌套处理

  7. TeacherMapper接口编写方法

    //获取指定老师,及老师下的所有学生
    public Teacher getTeacher(int id);
    
  8. 编写接口对应的Mapper配置文件(多了ofType的这个属性)

    <select id="getTeacher" resultMap="TeacherMap">
       select *
       from teacher
       where id = ;
    </select>
    <resultMap id="TeacherMap" type="Teacher">
       <id property="id" column="id"/>
       <result property="name" column="name"/>
       <!-- column是一对多的外键 , 写的是一的主键的列名 -->
       <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
    </resultMap>
    
    <select id="getStudent" resultType="Student">
       select *
       from student
       where tid = 
    </select>
    
  9. 进行测试

    2.3 按结果嵌套处理

  10. TeacherMapper编写方法

    //获取指定老师,及老师下的所有学生
    public Teacher getTeacher(int id);
    
  11. 编写接口对应的Mapper配置文件

    <select id="getTeacher" resultMap="TeacherMap">
       select t1.id tid, t1.name tname, t2.id sid, t2.name sname
       from teacher t1,
       student t2
       where t1.id = t2.tid
       and t1.id = ;
    </select>
    <resultMap id="TeacherMap" type="Teacher">
       <id property="id" column="tid"/>
       <result property="name" column="tname"/>
       <collection property="students" ofType="Student">
           <id property="id" column="sid"/>
           <result property="name" column="sname"/>
           <result property="tid" column="tid"/>
       </collection>
    </resultMap>
    
  12. 进行测试

  13. ResultMap总结

  14. 如果属性是JavaBean对象,则使用关联(association)

  15. 如果属性是集合,则使用集合(collection)

  16. 则association是用于一对一和多对一;collecion适用于一对多的关系

  17. javaType和ofType都是用于指定对象类型的

  18. javaType是用来指定pojo中属性的类型

  19. ofType指的是映射到list集合属性中的pojo的类型

    原文创作:linzeliang

    原文链接:https://www.cnblogs.com/linzeliang1222/p/14648627.html

更多推荐

更多
  • 程序计数器 M78 程序计数器简述特点作用似之处,都是取下一次的指令地址。 * PC Register在JVM里可以翻译成program counter register 程序计数器,在JVM里只存储当前执行的操作码的地址。也算是对CPU里寄存器的一种模拟
  • Java EE 学习 79 下 - 动态SQL - mybatis和spring的整合 - 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】一、动态SQL二、mybatis和spring的整合三、进行测试即可,测试使用的DAO/Service等在项目中。  1.动态SQL之多条件查询  2
  • 魔改swagger:knife4j的另外一种打开方式 魔改swagger:knife4j的另外一种打开方式一、两种文档聚合模式二、swagger-ui的实现原理三、swagger-register-server四、swagger-spring-boot-starter五、实战六、其它问题原
  • 二叉树题解方法 二叉树-题解-方法递归二叉树的递归遍历二叉树的迭代遍历二叉树的统一迭代法二叉树的层序遍历翻转二叉树对称二叉树二叉树的最大深度二叉树的最小深度慢就是快!递归法迭代法递归法迭代法迭代法n叉树的最大深度使用队列使用栈/15056076.htm
  • 字符串题解方法 字符串-题解-方法反转字符串反转字符串II替换空格翻转字符串左旋转字符串实现 strStr()重复的子字符串慢就是快!KMP算法KMP有什么用什么是前缀表时间复杂度分析代码,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题
  • Hash题解方法 Hash-题解-方法有效的字母异位词两个数组的交集快乐数两数之和四数相加II赎金信三数之和慢就是快!m", t = "nagaram" 输出: true 示例 2: 输入: s = "rat", t = "car" 输出: false
  • 链表题解 链表-题解移除链表元素翻转指针两两交换链表中的节点删除链表的倒数第N个节点链表相交环形链表II慢就是快!双指针法递归实现判断链表是否有环bo/2020/2465789-20210910160233590-1213910246.png)
  • 双指针题解 双指针-题解移除元素慢就是快!数组空间,你必须仅使用 O(1) 额外空间并**原地**修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例 1: 给定 nums = \[3,2,2,3\], ​ va
  • SprinBootSpringData整合 SprinBoot-SpringData-整合SpringData整合JDBC整合Druid整合MyBatis整合Redis慢就是快!JDBCTemplate配置数据源配置Druid数据源监控整合测试测试整合序列化配置自定义redisT
  • 刷题加油 刷题-加油推荐刷题网址方式慢就是快!ub中有好指导](https://programmercarl.com/) 想进大厂的朋友,建议刷够250-300题。 建议中等难度的占比不低于80%,简单的不超过10%。 另外选题类型尽量全面
  • 近期文章

    更多
    文章目录

      推荐作者

      更多