zoukankan      html  css  js  c++  java
  • Mybatis基础,利用mybatis实现复杂查询,多对一,一对多

    多个学生对应一个老师

    对于学生这边而言,关联..多个学生,关联一个老师【多对一】

    对于老师而言,集合,一个老师有很多个学生【一对多】

    注意:一对多相当与“对象”用(assocation)去处理

       多对一相当于”集合“用(collection)去处理

    一,环境搭建

    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');
    <!--到resources包和java包有重名包时默认合成一个包,特别是引全路径是注意-->

    pojo

    student

    package com.king.pojo;
    
    import lombok.Data;
    
    @Data
    public class Student {
        private int id;
        private String name;
    
        //学生需要关联一个老师
        private Teacher teacher;
    }

     teacher

    package com.king.pojo;
    
    import lombok.Data;
    
    @Data
    public class Teacher {
        private int id;
        private String name;
    
    }

    mappper测试

    package com.king.dao;
    
    
    import com.king.pojo.Teacher;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    public interface TeacherMapper {
    
        @Select("select * from teacher where id = #{tid}")
        public Teacher getTeacher(@Param("tid") int id);
    }
        <mappers>
            <mapper resource="com/king/dao/TeacherMapper.xml"/>
        </mappers>
    public class MyTest {
    
        @Test
        public void teacherTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = mapper.getTeacher(1);
            System.out.println(teacher);
            sqlSession.close();
    
        }
    }

    二,多对一查询方式:

        子查询

        联表查询

    练习,题目《查询所有学生信息以及对应老师的信息》

    方式一,按照查询嵌套处理(子查询)

    <mapper namespace="com.king.dao.StudentMapper">
    
        <!--
          思路:1.查询所有的学生信息
               2.根据查询出来的学生tid,寻找对应的老师
        -->
        <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 = #{id}
        </select>
    
    </mapper>

     拓展:为什么联表查询的过程是没有顺序的(不是先执行完表一再表二)?

    答:数据库是并发执行的

    方式二,按照结果进行嵌套处理(联表查询)

        <!--按照结果嵌套处理-->
        <select id="getStudent2" resultMap="StudentTeacher2">
            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>

    三,一对多查询

    3.1环境搭建

      实体类

    package com.king.pojo;
    
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    //一对多
    public class Teacher {
        private int id;
        private String name;
    
        //一个老师有很多学生
        private List<Student> students;
    }
    package com.king.pojo;
    
    
    import lombok.Data;
    
    @Data
    public class Student {
        private int id;
        private String name;
        private int tid;
    }

    3.2 mappper.xml实现

    方式一:根据结果查询(调试代码,改sql就可,推荐这种)

        <!--按结果嵌套查询-->
        <select id="getTeacher" resultMap="TeacherStudent">
            select s.id sid,s.name sname,t.id tid,t.name tname
            from student s,teacher t
            where s.tid=t.id and t.id=#{tid}
        </select>
        
        <resultMap id="TeacherStudent" type="Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
            <!--复杂的属性,我们需要单独处理,
                多对一(对象,association),javaType 指定属性的类型
                一对多(集合,collection),ofType 获取泛型信息
            -->
            <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 teachersTest() {
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = mapper.getTeacher(1);
            System.out.println(teacher);
            sqlSession.close();
        }

     

    方式二:select子嵌套

        <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

        3.1 javaType 用来指定实体类中属性的类型

        3.2 ofType  用来指定映射到List或者集合中的pojo类型,(泛型中约束的类型)

  • 相关阅读:
    linux shell获取用户输入
    yii2 笔记(1)
    yii2 数据库查询
    Yii2 环境配置生产环境和测试环境
    mysql 中find_in_set()和in()用法比较
    使用js提交form表单的两种方法
    base64编码的原理及实现
    浅析HTTP/2的多路复用
    Nginx 所使用的 epoll 模型是什么?
    git代码统计
  • 原文地址:https://www.cnblogs.com/CL-King/p/13875190.html
Copyright © 2011-2022 走看看