zoukankan      html  css  js  c++  java
  • Mybatis笔记(四):多对一的处理

    时间:2021/10/14

    一.目的

    这次我们构建的数据库表中存在多对一的关系,也就是多个学生对应一个老师。我们的目的是为了完成类似下面这种多表查询的操作:

    1 SELECT * FROM student s, teacher t WHERE s.tid = t.id;

    查询效果如下:

    以下是为了完了完成这种多对一关系的多表查询所需的准备工作和实际操作:

    二.创建数据库中相应的表

    这里我们在mybatis数据库中新建了两张表,分别是teacher表和student表,表中内容具体如下:

    要注意student表中的tid列作为外键与teacher表中的id列绑定。

    三.编写实体类

    Teacher.class:

     1 package bupt.machi.pojo;
     2 
     3 public class Teacher {
     4 
     5     private int id;
     6     private String name;
     7 
     8     public int getId() {
     9         return id;
    10     }
    11 
    12     public String getName() {
    13         return name;
    14     }
    15 
    16     public void setId(int id) {
    17         this.id = id;
    18     }
    19 
    20     public void setName(String name) {
    21         this.name = name;
    22     }
    23 
    24     @Override
    25     public String toString() {
    26         return "Teacher{" +
    27                 "id=" + id +
    28                 ", name='" + name + '\'' +
    29                 '}';
    30     }
    31 }

    Student.class:

     1 package bupt.machi.pojo;
     2 
     3 public class Student {
     4 
     5     private int id;
     6     private String name;
     7     //要注意这里不要写tid,要写对象teacher,体现一对多,自己并不是很理解
     8     //可能是为了简化后面的操作
     9     private Teacher teacher;
    10 
    11     public int getId() {
    12         return id;
    13     }
    14 
    15     public String getName() {
    16         return name;
    17     }
    18 
    19     public Teacher getTeacher() {
    20         return teacher;
    21     }
    22 
    23     public void setId(int id) {
    24         this.id = id;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     public void setTeacher(Teacher teacher) {
    32         this.teacher = teacher;
    33     }
    34 
    35     @Override
    36     public String toString() {
    37         return "Student{" +
    38                 "id=" + id +
    39                 ", name='" + name + '\'' +
    40                 ", teacher=" + teacher +
    41                 '}';
    42     }
    43 }

    要注意上面中属性teacher是一个对象,而不是数据库表中的tid,这位了更好的体现多对一的关系。

    四.编写接口

    StudentMapper.xml:

     1 package bupt.machi.dao;
     2 
     3 import bupt.machi.pojo.Student;
     4 
     5 import java.util.List;
     6 
     7 public interface StudentMapper {
     8 
     9     List<Student> getStudent();
    10 }

    TeacherMapper.xml:

     1 package bupt.machi.dao;
     2 
     3 import bupt.machi.pojo.Teacher;
     4 import org.apache.ibatis.annotations.Param;
     5 import org.apache.ibatis.annotations.Select;
     6 
     7 public interface TeacherMapper {
     8 
     9 //    @Select("select * from mybatis.teacher where id = #{tid}")
    10     Teacher getTeacherById(@Param("tid") int id);
    11 }

    五.编写Mapper配置文件

    之后我们会将Mapper配置文件放在resouces文件夹中,这样可以方便不同类型的文件之间的分离,但是要注意该配置文件的路径要和对应接口的路径一致,在resources中要用/,而不是Java包中的.来分隔。

    1)首先写一种结果不对的配置文件写法:

     1 <?xml version="1.0" encoding="UTF8" ?>
     2 <!DOCTYPE mapper
     3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 <!--绑定接口-->
     6 <mapper namespace="bupt.machi.dao.StudentMapper">
     7     <select id="getStudent" resultType="Student">
     8         select * from student
     9     </select>
    10 
    11 </mapper>

    当使用上面这种写法时,测试类运行出来的结果如下:

    这是因为数据库中查出来的tid与实体类中的Teacher属性无法对应,导致了值为null情况的出现。

    2)正确的配置文件写法

    • 第一种方法:按照查询嵌套处理,类似于子查询
     1 <?xml version="1.0" encoding="UTF8" ?>
     2 <!DOCTYPE mapper
     3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 <!--绑定接口-->
     6 <mapper namespace="bupt.machi.dao.StudentMapper">
     7     <select id="getStudent" resultMap="student">
     8         select * from student
     9     </select>
    10 
    11 <!--  这里的type是来说明结果的类型,本质上还是Student类型的  -->
    12     <resultMap id="student" type="Student">
    13 <!--  复杂的属性需要单独处理
    14       对象:association
    15       集合:collection
    16       -->
    17 <!--  由于属性teacher是一个对象,需要用javaType说明他的类,使用select指定的查询给他赋值      -->
    18         <association property="teacher" column="tid" javaType="teacher" select="getTeacherById"/>
    19     </resultMap>
    20     
    21     <select id="getTeacherById" resultType="teacher">
    22         select * from teacher where id = #{tid}
    23     </select>
    24 </mapper>

    具体讲解见注释,查询结果如下:

    • 第二种方法:按照结果嵌套处理,类似于联表查询
    <select id="getStudent2" resultMap="student2">
            select s.id sid, s.name sname, t.id tid, t.name tname from student s, teacher t where s.tid = t.id;
        </select>
        
        <resultMap id="student2" type="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <association property="teacher" javaType="Teacher">
                <result property="id" column="tid"/>
                <result property="name" column="tname"/>
            </association>
        </resultMap>

    查询结果如下:

  • 相关阅读:
    <<< List<HashMap<String, Object>> 及 HashMap<String, Object> 的用法
    <<< html图片背景平铺
    <<< javascript地址栏,代码
    Linux下常用目录有哪些?分别有什么作用?
    【Linux】Linux下进程间的通信方式
    【Linux】守护进程的定义,作用,创建流程
    【Linux】进程的结构,创建,结束,以及程序转化为的进程的过程
    【Linux】僵尸进程,孤儿进程以及wait函数,waitpid函数(有样例,分析很详细)
    【Linux】多线程同步的四种方式
    【Linux】多线程入门详解
  • 原文地址:https://www.cnblogs.com/machi12/p/15406114.html
Copyright © 2011-2022 走看看