MyBatis(八):高级结果映射

本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接

https://space.bilibili.com/95256449?spm_id_from=333.788.b_765f7570696e666f.2

联表查询

环境准备

  • 两个很简单的表,学生表记录了老师的pk

零、简单的联表查询

  • 以下两个实体类,学生表记录了老师的pk---->Teacher的id是Student的tid。

//省略了无参、有参构造、get、set、重写toString
public class Student {
    private int id;
    private String name;
    private int tid;
}
​
public class Teacher {
    private int id;
    private String name;
}
​
1.假如需求是查出每个学生的信息和对应老师的名字,那么sql语句应该是
 
select s.*,t,name from student s,teacher t where s.tid = t.id
2.直接把结果放在map里面就可以了
  • Mapper.xml

<mapper namespace="com.rzp.dao.StudentMapper">
    <select id="getByTeacher" resultType="map">
            select s.*,t.name as tname from student s,teacher t where t.id = s.tid
    </select>
</mapper>
  • Mapper接口
public interface StudentMapper {
    List<HashMap> getByTeacher();
}
  • 测试

    @Test
    public void getByTeacher(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<HashMap> studentList = mapper.getByTeacher();
        for (Map student : studentList) {
            //通过get方法可以直接取出来
            System.out.print(student.get("id")+"  ");
            System.out.print(student.get("name")+"  ");
            System.out.print(student.get("tid")+"  ");
            System.out.print(student.get("tname")+"  ");
            System.out.println();
        }
        sqlSession.close();
    }

3.这个方式如果只是做一些统计应该会比较好用,但是如果像这种情况还不如直接在Student里加一个temp属性,这样还能直接把List的泛型设置为Student,操作Student时还更方便。
4.但是以下两种情况就不好用了:
  • 如果实体类里的属性是另一个实体类对象时,比如Student里有一个Teacher对象的属性。

  • 又或者是实体类里的属性是另一个实体类的容器,比如Teacher里有一个Student的List。

  • 这时候就要使用结果集映射的对象(associtation )和集合(collection)属性。

  • 我的理解其实就是把普通结果集映射的properties替换成associtation而已,感觉就像是在xml文件里也定义了一个实体类,其中对象要用associtation来定义。

associtation

一、按照查询嵌套处理

  • Student里给了Teacher对象

//省略了无参、有参构造、get、set、重写toString
public class Student {
    private int id;
    private String name;
    private int tid;
    private Teacher teacher;
}
​
public class Teacher {
    private int id;
    private String name;
}
​
  • Mapper接口

public interface StudentMapper {
    //获取所有学生的信息
    List<Student> getAllStudent();
}
​
  • Mapper.xml

<mapper namespace="com.rzp.dao.StudentMapper">
    <!--查询所有学生和对应的老师,思路:
    1.查询所有的学生信息
    2.根据查询出来的学生tid寻找对应的老师
    -->
    <select id="getAllStudent" resultMap="StudentMap">
        select * from student
    </select>
    <resultMap id="StudentMap" type="Student">
        <!--复杂的属性,需要单独处理 对象:associtation 集合:collection-->
        <!--结果集映射中定义一个“对象”(associtation)属性
        property---student中这个对象的名称
        javaType---student中这个对象的类
        select---获取这个对象的查询语句(方法)
        column---使用这个语句要输入的参数,多个是column="{prop1=col1,prop2=col2}" 
        -->
        <association property="teacher" column="tid" javaType="Teacher" select="getAllStudendTest"/>
    </resultMap><select id="getAllStudendTest" resultType="Teacher">
        select * from teacher where id = #{id}
    </select>
</mapper>
        
  • 测试方法

    //查询所有学生
    @Test
    public void getAllTeacher(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> studentList = mapper.getAllStudent();
        for (Student student : studentList) {
            System.out.println(student);
        }
        sqlSession.close();
    }
​
  • 这个方式个人感觉不太符合一般联表查询的思维,更加像嵌套子查询。

二、按照结果嵌套处理

  • Mapper接口

     //按照结果嵌套处理
    List<Student> getAllStudent2();
  • Mapper.xml

    <select id="getAllStudent2" resultMap="StudentMap2">
        select s.id,s.name,s.tid,t.name tname
        from student s,teacher t
        where s.tid = t.id
    </select>
    <resultMap id="StudentMap2" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="tid" column="tid"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>
  • 测试

    //查询所有学生2
    @Test
    public void getAllTeacher2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> studentList = mapper.getAllStudent2();
        for (Student student : studentList) {
            System.out.println(student);
        }
        sqlSession.close();
    }

  • 备注:测试结果之中,teacher对象的id是0,个人觉得这个很像一个有参构造器。

collection

三、按照结果嵌套处理

  • 实体类

public class Student {
    private int id;
    private String name;
    private int tid;
}
public class Teacher {
    private int id;
    private String name;
    private List<Student> studentsList;
}

  • Mapper.xml

    <!--按结果嵌套查询-->
    <select id="getTeacherById" resultMap="TeacherMap">
        select s.*,t.name tname from student s,teacher t
        where s.tid = t.id and t.id = #{tid}
    </select><resultMap id="TeacherMap" type="Teacher">
        <result property="name" column="tname"/>
        <collection property="studentsList" ofType="Student" >
            <result property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
  • Mapper接口

    Teacher getTeacherById(@Param("tid") int id);
  • 测试

    @Test
    public void test1(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacherById(1);
        System.out.println(teacher);
        sqlSession.close();
    }
​

四、按查询嵌套处理

  • Mapper.xml

    <!--按查询嵌套处理-->
    <select id="getTeacherById2" resultMap="TeacherMap1">
        select t.* from teacher t where t.id = #{id}
    </select>

    <resultMap id="TeacherMap1" type="Teacher">
        <result property="id" column="id"/>
        <!--ofType--泛型-->
        <collection property="studentsList" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/>
    </resultMap>

    <select id="getStudent" resultType="Student">
        select * from student where tid = #{id}
    </select>
  • Mapper接口

   Teacher getTeacherById2(int id);
  • 测试

    @Test
    public void test2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacherById2(1);
        System.out.println(teacher);
        sqlSession.close();
    }

 

对比

  • 按结果查询,sql复杂,查询次数少,xml结构简单。

  • 按查询嵌套处理,sql简单,查询了多次,xml结构复杂。

个人觉得按结果查询更简单,xml结构复杂可能很难排错。

猜你喜欢

转载自www.cnblogs.com/renzhongpei/p/12590310.html
今日推荐