从入门到精通的使用Mybatis框架(九)——Mybatis一对多,多对一的处理

多对一的处理

举个简单的例子来理解多对一:学生和老师
多个学生对应一个老师
如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师
在这里插入图片描述

NAME VARCHAR(20) DEFAULT NULL,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(id,NAME) VALUES(1,"Pteacher")

CREATE TABLE student(
id INT(10) NOT NULL,
NAME VARCHAR(30) DEFAULT NULL,
tid INT(10) NOT 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,"pag",1),(2,"fff",1), (3,"ppp",1),(4,"aaa",1),(5,"ggg",1);

搭建测试环境

maven安装Lombok

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
</dependency>

在代码中的使用

teacher类

 @Data //GET,SET,ToString,有参,无参构造
 public class teacher {
     private int id;
     private String name;
 }

student类

 @Data
 public class student {
     private int id;
     private String name;
     //多个学生可以是同一个老师,即多对一
     private Teacher teacher;
 }
按查询嵌套处理

studentMapper接口:

public List<Student> getStudent();

studentMapper.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.PAG.mapper.studentMapper">
    <!--
      需求:获取所有学生及对应老师的信息
      思路:
          1. 获取所有学生的信息
          2. 根据获取的学生信息的老师ID->获取该老师的信息
          3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
              1. 做一个结果集映射:StudentTeacher
              2. StudentTeacher结果集的类型为 Student
              3. 学生中老师的属性为teacher,对应数据库中为tid。
                 多个 [1,...)学生关联一个老师=> 一对一,一对多
              4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询
      -->
    <select id="getStudent" resultMap="studentTeacher1">
        select * from student
    </select>

    <resultMap id="studentTeacher1" type="Student">
        <!--association关联属性  property属性名 javaType属性类型 column在多的一方的表中的列名-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
<!--        <association property="teacher"  column="{id=tid,name=tid}" javaType="Teacher" select="getTeacher"/>-->
    </resultMap>

    <!--
    这里传递过来的id,只有一个属性的时候,下面可以写任何值
    association中column多参数配置:
        column="{key=value,key=value}"
        其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
    -->
    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id = #{id}
    </select>
    <!--    select * from teacher where id = #{id} and name = #{name}-->
</mapper>

测试类:

    @Test
    public void getStudent(){
        SqlSession session = MybatisUtils.getSession();
        studentMapper mapper = session.getMapper(studentMapper.class);
        for (student student : mapper.getStudent()) {
            System.out.println("studentName:"+student.getName()
            +"  teacherName:"+student.getTeacher().getName()
            );
        }
        session.close();
    }
按结果嵌套处理

studentMapper接口:

public List<Student> getStudent1();

studentMapper.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.PAG.mapper.studentMapper">
      <!--
    按查询结果嵌套处理
    思路:
    1. 直接查询出结果,进行结果集的映射
-->
    <select id="getStudent1" resultMap="studentTeacher">
        select s.id sid,s.name sname,t.name tname
        from student s,teacher t
        where s.tid = t.id
    </select>
    <resultMap id="studentTeacher" type="student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!--关联对象property 关联对象在Student实体类中的属性-->
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>
</mapper>

测试类:

    @Test
    public void getStudent1(){
        SqlSession session = MybatisUtils.getSession();
        studentMapper mapper = session.getMapper(studentMapper.class);
        for (student student : mapper.getStudent1()) {
            System.out.println("studentName:"+student.getName()
                    +"  teacherName:"+student.getTeacher().getName()
            );
        }
        session.close();
    }

一对多的处理

一对多的理解:

一个老师拥有多个学生
如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)

实体类

teacher类

package com.PAG.pojo;

import lombok.Data;

import java.util.List;

@Data//GET SET ToString 有参 无参
public class teacher {
    private int id;
    private String name;
    //一个老师带多个学生
    private List<student> students;
}

student类

package com.PAG.pojo;

import lombok.Data;

@Data
public class student {
    private int id;
    private String name;
    private int tid;
}

按查询嵌套处理

teacherMapper接口

    public teacher getTeacher(int id);

teacherMapper.xml

        <!--
       思路:
           1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
           2. 对查询出来的操作做结果集映射
               1. 集合的话,使用collection!
                   JavaType和ofType都是用来指定对象类型的
                   JavaType是用来指定pojo中属性的类型
                   ofType指定的是映射到list集合属性中pojo的类型。
       -->
    <select id="getTeacher" 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>

测试类

    @Test
    public void getTeacher(){
        SqlSession session = MybatisUtils.getSession();
        teacherMapper mapper = session.getMapper(teacherMapper.class);
        teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher.getName());
        System.out.println(teacher.getStudents());
        session.close();
    }

按结果嵌套处理

teacherMapper接口

    public teacher getTeacher1(int id);

teacherMapper.xml

<select id="getTeacher1" resultMap="teacherStudent1">
        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 = #{id}
    </select>
    <resultMap id="teacherStudent1" 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>

测试类

    @Test
    public void getTeacher1(){
        SqlSession session = MybatisUtils.getSession();
        teacherMapper mapper = session.getMapper(teacherMapper.class);
        teacher teacher1 = mapper.getTeacher1(1);
        System.out.println(teacher1.getName());
        System.out.println(teacher1.getStudents());
        session.close();
    }

小结

关联-association
集合-collection

association是用于一对一和多对一,而collection是用于一对多的关系

JavaType和ofType都是用来指定对象类型的

  • JavaType是用来指定pojo中属性的类型
  • ofType指定的是映射到list集合属性中pojo的类型。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FFFPAG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值