Mybatis的集合查询

来源:互联网 发布:官方经纬度定位软件 编辑:程序博客网 时间:2024/06/05 06:47

Mybatis的集合查询

这次在自己练的项目中遇到了一个数据结构比较恶心的返回数据

[  {    className: "三年级一班",    students: [      { name: "学生甲", id: "xxx" },      { name: "学生乙", id: "xxx" },      { name: "学生丙", id: "xxx" },    ]  },  {    className: "三年级二班",    students: [      { name: "学生甲", id: "xxx" },      { name: "学生乙", id: "xxx" },      { name: "学生丙", id: "xxx" },    ]  }]

这个返回的数据需要用到数据库表(其中user表中包括了学生跟老师的),如下:

user(userId,classId)teacher_class(teacherId,classId)classes(classId,gradeId,className)grade(gradeId,gradeName)

一开始,我的思路就是先用老师Id获取对应的班级列表后,接着for循环进行班级列表的遍历,紧接着就是根据班级的Id获取班级中的学生。但是,如果这样意味着获取如果一个老师有多个班,获取一次这个老师所教的所有学生将多次访问数据库,这样将会建立多次数据库的链接,这将会浪费数据库资源。在初次尝试中,我就是这样做的,并且有一个sql判断写错,造成了一次500次的数据库连接,直接出现了too many connection的报错。
因此,在这里我将说说我最后解决上述问题,用的Mybatis集合查询的心得。
Mybatis集合查询适合于映射于StudentsDto这样的实体类

public class StudentsDto {    private String classId;    private String className;    private List<GetStudentDto> students;    public String getClassId() {        return classId;    }    public void setClassId(String classId) {        this.classId = classId;    }    public String getClassName() {        return className;    }    public void setClassName(String className) {        this.className = className;    }    public List<GetStudentDto> getStudents() {        return students;    }    public void setStudents(List<GetStudentDto> students) {        this.students = students;    }}

其中的GetStudentDto类如下:

public class GetStudentDto {    private String name;    private String id;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }}

接着,就是配置mapper.xml文件

<resultMap id="StudentsDto" type="com.edu.dto.StudentsDto">    <result property="classId" column="classId" />    <result property="className" column="className" />    <collection property="students" javaType="ArrayList" column="getStudentDtos" ofType="com.edu.dto.GetStudentDto">        <result property="id" column="userid" />        <result property="name" column="username" />    </collection></resultMap>
<select id="getStudentsByTeacherId" resultMap="StudentsDto">    select        tcr.classId as classId,        concat(g.gradeName,c.className) as className,        u.userId as userid,        u.name as username    from         teacher_class_relationship tcr        join classes c on tcr.classId=c.classId        join grade g on c.gradeId=g.gradeId        join user u on u.classId=c.classId    where        teacherId=#{teacherId}</select>

在resultMap标签中的id=”StudentsDto”就是一个标识,便于下面select标签引用,type的值就是整个resultMap的bean注入实体的对象位置。接下来的result标签就是普通字段,如果是主键字段就是id标签。在result与id标签中,有两个常用属性property和column。property就是对应实体中的字段名,column就是对应数据库字段名。
接下来就是collection标签,在collection标签中有几个常用属性,property字段值对应resultMap中引用实体的字段名,javaType就是对应的java数据类型,column就是指定的sql查询结果的字段名或字段别名,ofType就是collection的bean注入实体的对象位置。
按照这样写好后,就可以一次性的取到一开始讨论的返回数据

[    {        "className": "二年级二班",        "students": [            {                "name": "吴XX",                "id": "03b04eef-1c61-4b05-basc-7af95f6d26dc"            },            {                "name": "文XX",                "id": "1123553f-3fas-4b09-aabf-1ce331b8b5b4"            },            {                "name": "王XX",                "id": "12a3e6bd-7f45-4d56-bsde-2d4b922e1ab3"            }        ]    },    {        "className": "一年级一班",        "students": [            {                "name": "刘XX",                "id": "1227929f-c83c-48fe-8db4-bd0as4e5d5f7"            },            {                "name": "沈XX",                "id": "1eb50dfa-3712-4150-92b3-9ba5sddd325"            },            {                "name": "李XX",                "id": "1fa73f79-2de0-4a0b-b478-46f2as098db"            }        ]    }]