• MyBatis多对一SQL查询


    1、多对一的概念

    • 多个学生,对应一个老师

    • 对于学生而言,多个学生关联一个老师 (关联)【多对一】

    • 对于老师而言,一个老师有多个学生(集合)【一对多】

      image-20210112143131703

    2、搭建数据库

    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');
    

    3、搭建项目环境

    1. 编写实体类

      学生类Student

      public class Student {
          private Integer id;
          private String name;
          //多个学生可以是同一个老师,即多对一
          private Teacher teacher;
          // 构造器
          // toString
          // getter and setter
      }
      

      老师类Teacher

      public class Teacher {
          private Integer id;
          private String name;
          // 构造器
          // toString
          // getter and setter
      }
      
    2. 编写实体类对应的mapper接口文件

      无论是否使用,都应该编写,以备后来之需

      public interface StudentMapper {
      }
      
      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="com.jh.mapper.StudentMapper">
      
      </mapper>
      
      <?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="com.jh.mapper.TeacherMapper">
      
      </mapper>
      
    4. 在核心配置文件中注册xml文件

      <mappers>
          <mapper class="com.jh.mapper.TeacherMapper"/>
          <mapper class="com.jh.mapper.StudentMapper"/>
      </mappers>	
      

    4、按照查询嵌套处理

    需求:获取所有学生及对应老师的信息

    思路

    1. 查询所有的学生信息
    2. 根据学生信息中的老师tid,查询对应的老师信息
    3. 返回值中包含了teacher的消息resultType不可用,怎么解决?
      1. 使用结果集映射:resultMap
      2. resultMap的type是Student
      3. student中的属性为teacher,对应数据库中为tid
      4. 使用association实现复杂类型的关联,处理关联查询

    具体实现

    1. 编写mapper接口方法

      public interface StudentMapper {
          List<Student> getStudentList();
      }
      
    2. 编写xml配置文件

      <select id="getStudentList" resultMap="studentTeacher">
          select * from student;
      </select>
      <resultMap id="studentTeacher" type="com.jh.domain.Student">
          <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
          <association property="teacher" column="tid" javaType="com.jh.domain.Teacher" select="getTeacher"/>
      </resultMap>
      <!--
      	这里传递过来的id,只有一个属性的时候,下面可以写任何值
      	association中column多参数配置:
             column="{key=value,key=value}"
      	其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
      -->
      <select id="getTeacher" resultType="com.jh.domain.Teacher">
          select * from teacher where id = #{id};
      </select>
      
    3. 编写测试

      测试结果如下

      Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
      

    5、按照结果嵌套处理

    除了上面这种方式,我们还可以按照结果进行嵌套处理;

    1. 编写mapper接口

      public interface StudentMapper {
          List<Student> getStudentList();
      }
      
    2. 编写xml配置文件

      <!-- 按照结果嵌套处理 -->
      <select id="getStudentList" resultMap="StudentTeacher">
          select s.id sid, s.name sname, t.id tid, t.name tname
          from mybatis.student s,
               mybatis.teacher t
          where s.id = t.id;
      </select>
      
      <resultMap id="StudentTeacher" type="com.jh.domain.Student">
          <id property="id" column="sid"/>
          <result property="name" column="sname"/>
          <!-- 关联对象property关联对象在Student实体类中的属性 -->
          <association property="teacher" javaType="com.jh.domain.Teacher">
              <result column="tname" property="name"/>
              <result column="tid" property="id"/>
          </association>
      </resultMap>
      
    3. 测试结果

      Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}}
      Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
      

    总结

    • 按照查询进行嵌套处理就像SQL中的子查询
    • 按照结果进行嵌套处理就像SQL中的联表查询
    懂不懂,都是收获
  • 相关阅读:
    A B
    hdu 4656 Evaluation [任意模数fft trick]
    bzoj 3451: Tyvj1953 Normal [fft 点分治 期望]
    bzoj 3509: [CodeChef] COUNTARI] [分块 生成函数]
    hdu 5730 Shell Necklace [分治fft | 多项式求逆]
    hdu 4609 3-idiots [fft 生成函数 计数]
    UVA 12633 Super Rooks on Chessboard [fft 生成函数]
    Codeforces Round #410 (Div. 2)
    形式幂级数 [学习笔记]
    Python 字符串前面加u,r,b,f的含义
  • 原文地址:https://www.cnblogs.com/paidaxing0623/p/14268923.html
Copyright © 2020-2023  润新知