mybatis学习——多对一和一对多查询

首先先来说明一下数据库,数据库有两张表student表和teacher表:

student表如下:

teacher表如下:

两张表的关系:多个学生关联一位老师(多对一)

*其中tid是外键

需要sql语句的朋友可以在这里取:

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

SELECT * FROM student;
SELECT * FROM teacher;
View Code

下面进入正题:

一、多对一

1.编写pojo类

注意:在“多”这一边添加一个“一”的对象作为属性。例如:在student实体类中添加一个属性 Teacher teacher;

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

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

注意:@Data是一个注解,使用这个注解可以自动帮我们引入get()、 set()、 toString()等方法。这个注解来自lombok,要使用这个注解首先要安装lombok插件并导入相关jar包。

2.编写接口类

public interface StudentMapper {
    public List<Student> getStudent();
}

3.编写映射文件

这里有两种方法,按照查询嵌套处理和按照结果嵌套处理

方式一:按照查询嵌套处理

思路:我们先查询所有的学生,然后根据查询出来的学生的tid再去查询对应的老师的信息,代码如下所示

<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.orggetStudent//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.StudentMapper">

    <select id="getStudent" resultMap="StudentTeacher">
        SELECT * FROM student
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
  <select id="getTeacher" resultType="Teacher">
        SELECT * FROM teacher where id = #{tid}
    </select>
</mapper>

注意:

  ●用来指定实体类中属性的类型。还不懂的话,那就再细说一点:由于上边代码<association >标签中properties的值是teacher,实体类Student中teacher属性的类型是Teacher,所以javaType="Teacher"

    

  ●在上边代码中<resultMap>标签里简单的属性我们可以用<result>标签去映射,但是复杂的属性就用不了了,那怎么结局复杂属性的映射怎么解决呢?有两种情况:

    ①.复杂属性是对象:用association

    ②.复杂属性是集合,用collection

映射过程图解:

方式二:按照结果嵌套处理

这种方法比较简单,只要对比上一种方法你就能明白了,这里就不详细赘述了。

映射文件代码如下:

<!--方式二-->
<select id="getStudent2" resultMap="StudentTeacher2">
SELECT s.id AS sid,s.name AS sname,t.id AS tid,t.name AS 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="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>

注意:

●select语句中给字段区别名那里不能省略,不然查询结果会出错。出错的原因我现在不知道,有知道的朋友欢迎在下边评论,不胜感谢!

二、一对多

1.编写pojo类

*tip:在“一”这一边添加一个“多”的对象的泛型集合作为属性。例如:在Teacher 实体类中添加一个属性 List<Student> students;

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

注意:@Data是一个注解,使用这个注解可以自动帮我们引入get()、 set()、 toString()等方法。这个注解来自lombok,要使用这个注解首先要安装lombok插件并导入相关jar包。

2.编写接口类

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

3.编写映射文件

这里有两种方法,按照查询嵌套处理和按照结果嵌套处理

方式一:按照查询嵌套处理

思路:我们先根据id查询所有的老师,然后根据查询出来的老师的id再去查询对应的学生的信息,代码如下所示

<?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.kuang.dao.TeacherMapper">
    <select id="getTeacher" resultMap="TeacherStudent">
        SELECT * FROM teacher WHERE id = #{tid}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
    </resultMap>

    <select id="getStudentByTeacherId" resultType="Student">
        SELECT * FROM student WHERE tid = #{tid}
    </select>
</mapper>

注意:

  ●javaType:用来指定实体类中属性的类型。还不懂的话,那就再细说一点:由于上边代码<collection >标签中properties的值是students,实体类Teacher中students属性的类型是一个泛型列表ArrayList,所以javaType="ArrayList"

  ●ofType:用来指定映射到集合中的pojo类型,泛型中的约束类型。

方式二:按照结果嵌套处理

  <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 = #{tid} AND s.tid = t.id
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result column="tid" property="id"/>
        <result column="tname" property="name"/>
        <collection property="students" javaType="ArrayList" ofType="Student">
            <result column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="tid" property="tid"/>
        </collection>
    </resultMap>
原文地址:https://www.cnblogs.com/bear7/p/12511088.html