zl程序教程

您现在的位置是:首页 >  后端

当前栏目

哪吒Java技能树--MyBaits学习笔记--关联和集合对应着多对一和一对多(“最易懂得MyBatis学习”)

2023-09-11 14:20:20 时间

前 言 : \textcolor{blue}{前言:}
💥gitee中MyBatis学习源码💥所用到的代码都可以在这里找到

点一下送你到Gitee
xiaolinH

十、多对一处理

  • 多个学生对应一个老师

  • 对于学生这边:关联,多个学生关联一个老师【多对一】

  • 对于老师这边:集合,一个老师又很多学生【一对多】

1. 基本环境搭建

1.1 创建数据库表

#数据库里面的`teacher`是键盘Tab上面的,而'王老师'这里的'是回车左边的
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);

1.2 导入Lombok

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
    </dependency>
</dependencies>

1.3 新建实体类Teacher,Student

@Data
public class Teacher {
    private int id;
    private String name;
}
@Data
public class Student {
    private int id;
    private String name;
    //学生需要关联一个老师
    private Teacher teacher;
}

1.4 建立Mapper接口

import com.hxl.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface TeacherMapper {

    @Select("select * from teacher where id = #{tid}")
    Teacher getTeacher(@Param("tid")int id);
}
public interface StudentMapper {
}

1.5建立Mapper.xml文件

这个地方创建mapper.xml文件时,需要注意创建的包一定可以展开否则会报错。

查看可以展开包的方式可以阅读这篇文章。

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<mapper namespace="com.hxl.dao.TeacherMapper">

</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--核心配置文件-->
<mapper namespace="com.hxl.dao.StudentMapper">

</mapper>

1.6 在核心配置文件中绑定注册我们的Mapper接口或者文件

这里如果使用class就必须让TeacherMapper和TeacherMapper.xml在同一个文件下。

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

1.7 测试查询是否能够成功

public class myTest {
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }
}

2. 按照查询嵌套处理

复杂的属性,我们需要单独处理. 对象:association 集合:collection
javaType=""指定属性的类型! 集合中的泛型信息,我们使用ofType获取

public interface StudentMapper {
    //查询所有的学生信息,以及对应的老师的信息
    public List<Student> getStudent();
}
<mapper namespace="com.hxl.dao.StudentMapper">
    <!--方式一:按照查询嵌套处理
    思路:
        1.查询所有的学生信息
        2.根据查询出来的学生tid,寻找对应的老师
    -->
    <resultMap id="studentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性,我们需要单独处理. 对象:association   集合:collection -->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getStudent" resultMap="studentTeacher">
        select * from student;
    </select>
    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id = #{id};
    </select>
</mapper>

在这里插入图片描述

3. 按照查询嵌套处理

<!--方式二:按照结果嵌套处理-->
<select id="getStudent2" resultMap="Student2">
    select s.id sid, s.name sname, t.name tname from student s, teacher t where s.tid = t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

在这里插入图片描述

  • 回顾Mysql多对一查询方式

    • 子查询
    • 联表查询

十一、一对多处理

比如:一个老师拥有多个学生

对于老师而言,就是一对多的关系。

1. 环境搭建

和之前的一样,将之前的copy过来,然后把实体类进行修改

@Data
public class Student {
    private int id;
    private String name;

    private int tid;
}
@Data
public class Teacher {
    private int id;
    private String name;
    //一个老师拥有多个学生
    private List<Student> students;
}

接口中进行方法编写

public interface TeacherMapper {

    //获取所有老师
    //List<Teacher> getTeacher();

    //获取指定老师下的所有学生及老师的信息
    Teacher getTeacher(@Param("tid") int id);

    Teacher getTeacher2(@Param("tid") int id);
}

2. 按照结果嵌套处理

<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, s.name sname,t.name tname,t.id tid from student s,teacher t where t.id = s.tid and t.id = #{tid};
</select>
<!--按结果嵌套查询-->
<resultMap id="TeacherStudent" type="Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <!--复杂的属性,我们需要单独处理. 对象:association   集合:collection -->
    <!--javaType=""指定属性的类型!
    集合中的泛型信息,我们使用ofType获取
    -->
    <collection property="students" ofType="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

在这里插入图片描述

3. 按照查询嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
    select * from teacher where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
    <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
    select * from student where tid = #{tid}
</select>

在这里插入图片描述

小结

  1. 关联-association【多对一】
  2. 集合-collection【一对多】
  3. javaType & ofType
    • javaType用来指定实体类中属性的类型
    • ofType用来指定映射到List或者集合张的pojo类型,泛型中的约束类型

注意点:

  • 保证sql的可读性,尽量保证通俗易懂
  • 注意一对多和多对一中,属性名和字段的问题
  • 如果问题不好排查错误,可以使用日志,建议使用Log4j

结果映射:结果映射

面试高频

M y S Q L 引 擎 ; I n n o D B 底 层 原 理 ; 索 引 ; 索 引 优 化 。 \textcolor{red}{ MySQL引擎; InnoDB底层原理; 索引; 索引优化。 } MySQL;InnoDB;;