zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    postman+newman+jenkins 接口自动化问题
    rabbitMQ Management http://localhost:15672/ 打不开
    转-轻松几步搭建SVN服务器
    Eclipse调优
    转- 关于时间,日期,星期,月份的算法(Java中Calendar的使用方法)
    calculate Leave Days
    验证只能输入中文
    js 只能限制只能输入数字和转大写方法
    拿来自勉
    JAVA的容器---List,Map,Set的区别
  • 原文地址:https://www.cnblogs.com/bear7/p/12511088.html
Copyright © 2011-2022 走看看