MyBatis一对多SQL查询

1、一对多的概念

例如:一个老师有多个学生!

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

2、搭建环境

  1. 编写实体类

    public class Teacher {
        private Integer id;
        private String name;
        // 一个老师拥有多个学生,一对多
        private List<Student> students;
        // 构造器
        // toString
        // getter and setter
    }
    
    public class Student {
        private Integer id;
        private String name;
        private Integer tid;
        // 构造器
        // toString
        // getter and setter
    }
    
  2. 编写实体类对应的mapper接口

    public interface StudentMapper {
    }
    
    public interface TeacherMapper {
    }
    
  3. 编写mapper接口对应的xml文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.jh.mapper.TeacherMapper">
    
    </mapper>
    
  4. 测试环境是否成功

    public class TeacherMapperTest {
        @Test
        public void getTeacher() {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = teacherMapper.getTeacher(1);
            System.out.println(teacher);
            sqlSession.close();
        }
    }
    

3、按照结果嵌套处理

获取指定老师下的所有学生及老师信息

思路:

  • 从学生表和老师表中查出学生id,学生姓名,老师姓名
  • 对查询出来的操作做结果集映射
    1. 集合使用collection标签
    2. JavaType和ofType都是用来指定对象类型的
    3. JavaType是用来指定pojo中属性的类型
    4. ofType指定的是映射到list集合属性中pojo的类型

具体实现:

  1. 编写mapper接口方法

    public interface TeacherMapper {
        Teacher getTeacher(@Param("tid") int id);
    }
    
  2. 编写xml

    <select id="getTeacher" resultMap="TeacherStudent">
        select t.id tid, t.name tname, s.id sid, s.name sname
        from mybatis.teacher t,
             mybatis.student s
        where s.tid = t.id
          and t.id = #{tid}
    </select>
    
    <resultMap id="TeacherStudent" type="com.jh.domain.Teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="com.jh.domain.Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
    
  3. 测试

    @Test
    public void getTeacher() {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = teacherMapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }
    
  4. 测试结果

    Teacher{id=1, name='廖老师', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小红', tid=1}, Student{id=3, name='小张', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
    

4、按照查询嵌套处理

使用子查询方式查询

  1. 编写mapper接口方法

    public interface TeacherMapper {
        Teacher getTeacher(@Param("tid") int id);
    }
    
  2. 编写xml

    <select id="getTeacher" resultMap="TeacherStudent">
        select * from mybatis.teacher where id = #{tid};
    </select>
    
    <resultMap id="TeacherStudent" type="com.jh.domain.Teacher">
        <!--column是一对多的外键 , 写的是一的主键的列名-->
        <collection property="students" javaType="ArrayList" ofType="com.jh.domain.Student" select="getStudent" column="id"/>
    </resultMap>
    
    <select id="getStudent" resultType="com.jh.domain.Student">
        select * from mybatis.student where tid = #{tid}
    </select>
    
  3. 测试结果

    Teacher{id=null, name='廖老师', students=[Student{id=1, name='小明', tid=1}, Student{id=2, name='小红', tid=1}, Student{id=3, name='小张', tid=1}, Student{id=4, name='小李', tid=1}, Student{id=5, name='小王', tid=1}]}
    

小结

  1. 关联-association【多对一】
  2. 集合-collection【一对多 】
  3. association是用于一对一和多对一,而collection是用于一对多的关系
  4. JavaType和ofType都是用来指定对象类型的
    1. JavaType是用来指定pojo中属性的类型
    2. ofType指定的是映射到list集合属性中pojo的类型,泛型中的约束类型!

注意点

  1. 保证SQL的可读性,尽量通俗易懂
  2. 根据实际要求,尽量编写性能更高的SQL语句
  3. 注意属性名和字段不一致的问题
  4. 注意一对多和多对一 中:字段和属性对应的问题
  5. 建议使用Log4j,通过日志来查看自己的错误
posted @ 2021-01-12 19:32  天下御免  阅读(136)  评论(0编辑  收藏  举报