MyBatis~关联的嵌套Select查询和关联的嵌套结果映射(association元素的使用)、集合的嵌套Select查询和集合的嵌套结果映射(collection的使用)

解决一对多数据问题

  • 在一对多的数据表结构中,比如一个老师教育着很多学生, 对于学生而言, 这就是一个一对多的问题
  • 这个主要解决的就是如果我们的POJO对象的属性中,有一个是引用类型,不是基本类型或者String, 那么简单的sql语句肯定是解决不了的
  • 学生类型
public class Student {

    private int id;
    private String name;
    private Teacher teacher;
}
  • 老师类型
public class Teacher {

    private int id;
    private String name;
}
  • 比如我们现在有一个需求, 要查找数据库中所有的学生对象, 该如何做?

关联的嵌套 Select 查询

    <select id="selectStudent" resultMap="studentTeacher">
        select * from student;
    </select>

    <resultMap id="studentTeacher" type="student">
        <association property="teacher" javaType="teacher" column="tid" select="selectOneTeacher"/>
    </resultMap>

    <select id="selectOneTeacher" resultType="teacher">
        select * from teacher where id=#{tid};
    </select>
  • 带你解读一下上面的代码, 首先id对应的是我们dao层接口的方法 ,返回值类型我们初始设置成resultmap, 首先查到的是数据库学生表的所有信息
  • 然后到resultMap标签里, 这里的id要对应上述我们设置的resultMap的名子, 这个这个返回类型就是真实的返回类型, 所以是student, 其中student的id和name已经自动映射好了, 不需要我们再次建立映射关系, 最重要的就是teacher对象的映射, 我们使用association标签,property映射到student类型的teacher引用名, Javatype表示返回的是一个teacher类型, column表示所查到的学生信息中的tid要去这个老师对象建立连接, select表示调用下面的select语句
  • 在最下面的select语句中,返回类型是teacher类型与上面进行对应, 在sql语句中通过上面的column设定的列的值进行对应建立连接
  • 最后就是返回student这个对象
    在这里插入图片描述

关联的嵌套结果映射

    <select id="selectStudent2" 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 column="sid" property="id"/>
        <result column="sname" property="name"/>
        <association property="teacher" javaType="teacher">
            <result column="tname" property="name"/>
        </association>
    </resultMap>
  • 使用这个代码易懂, 但是sql语句会变得复杂
  • 一开始我们便使用很长的sql语句建立老师和学生的连接将所有信息查询出来
  • 所以在resultmap中我们只需要将这些信息进行结果映射即可, 但是要注意引用类型的结果映射还得在association元素内使用, 还需指定返回的类型
  • 注意我没有设置老师id的这个属性的映射关系, 所以查到显示的肯定是这个数据类型的默认值
    在这里插入图片描述

解决一对多问题

  • 还是最开始的那个例子, 一个老师教育很多学生, 对于老师而言这就是一对多的关系, 但是在这里我想复杂一下就是一个班级既有老师,又有学生, 也就是既有引用类型, 又有集合类型, 这种该如何查询
  • 好, 我现在有一个需求 ,我指定老师的id 要得到这个教室的所有信息, 包括老师的信息和所有学生的信息
  • 教室类型
public class ClassRoom {

    private Teacher teacher;
    private List<Student> students;
}

集合的嵌套Select查询

    <select id="getClassRoom" parameterType="_int" resultMap="classRoomMap">
        select * from teacher where id=#{tid};
    </select>

    <resultMap id="classRoomMap" type="classRoom">
        <association property="teacher" javaType="teacher">
            <result column="id" property="id"/>
            <result column="name" property="name"/>
        </association>
        <collection property="students" javaType="ArrayList" ofType="student" column="id" select="students"/>
    </resultMap>

    <select id="students" resultType="student">
        select id, name from student where tid=#{id};
    </select>
  • 首先最开始id对象方法名是getClassRoom, 通过老师的id查找, 所以会有一个参数parameterType是int型的, 初步返回类型是resultmap, 在初步的sql语句中,我通过老师的id找到这个老师的所有信息
  • 在resultMap的对应名称classRoomMap里, 我指定返回类型当然是一个classroom类型, 接下来就是使用association元素对老师这个引用进行属性建立映射关系
  • 接下来使用collection这个元素对学生这个集合进行构造, 首先明确使用collection这个元素, 你首先是要与classroom的属性名建立映射练习, 然后必须指定javatype和oftype, javatype是java中的什么集合类型, oftype是指定这个集合类型中的泛型参数的什么类型的,这个很重要, 然后column指定通过什么数据与后面的select建立联系
  • 在最后的select中, 我们通过上述column传来的teacher的id与所有学生的替代建立联系, 查到对应要求的信息, 返回student类型, 值此再返回classRoom这个类型的查询结果

在这里插入图片描述

集合的嵌套结果映射

  • 这里需要改一个东西, 就是如果要满足我们的需求, 使用上面的classroom类型如果使用集合的嵌套结果映射在SQL层面是实现不了的, 所以得把classroom的数据类型改一下
  • 新的教室类型
public class ClassRoom {

    private int tid;
    private String tname;
    private List<Student> students;
}
  • ok
    <select id="getClassRoom2" parameterType="_int" resultMap="classRoomMap2">
        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="classRoomMap2" type="classRoom">
            <result column="tid" property="tid"/>
            <result column="tname" property="tname"/>
        <collection property="students" javaType="ArrayList" ofType="student">
            <result column="sid" property="id"/>
            <result column="sname" property="name"/>
        </collection>
    </resultMap>
  • 只要使用的是结果集的映射, 就是一开始就将所有信息都查出来, 然后在一个resultMap中进行属性名与数据库表中列的字段名建立连接
  • 但是还是要注意这里的sql语句是比上面的复杂的, 而且要留意只要使用collection元素, 就必须设置其中的Javatype和oftype, 这点很重要
    在这里插入图片描述

小结

  1. 关联association, 用于属性中有对象时使用, 用于一对多的环境
  2. 集合collection, 用于属性中有集合类型的时候使用,用于多对一的环境
  3. javatype, 用来指定java中指定实体属性中的类型, 就好比这个指定的是List类型
  4. oftype, 用来指定映射到java指定实体属性集合中泛型的具体类型,这个指定的就是List中Studente类型
  5. 如果需要使用引用类型, association, 只需注明属性名称, 注明javatype, 然后在里面进行设置值即可
  6. 如果是集合类型,使用collection,注明属性名称, 注明javatype类型, 和集合类型里面的泛型类型oftype, 然后在里面result值即可.

注意点:

  1. 保证sql的可读性, 尽量保证通俗易懂
  2. 注意多对一和一对多中属性名和字段名的匹配问题, 多用于日志
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页