目录 概述 业务层进行联合 DAO 层进行联合 分步骤联合查询 统一联合查询 查询关联集合对象 附录 在项目中经常遇到多表联合查询的情况,通过逆向生成的 Mapper 并不能够完成这项任务,所以多表联合需要手动编写,那么如何操作才能够写出优雅的联合查询尼?
概述 有这样一个例子:一个学生可以有多个老师,一个老师也可以传授知识给多个学生
这里主要给出两个解决办法:
业务装配对两个表写单独的 sql 语句,在业务(service)把查询结果进行联合 使用 Mybatis 的<resultMap>
标签进行实现 业务层进行联合 使用业务层进行联合处理,可以在需求更改的条件下,减少修改面的蔓延程度,但是在实际项目中,这么做可能影响服务性能,毕竟是在 Service 手动进行操作,当然没有数据库自身操作快捷
DAO 层进行联合 这种方式可以使用<resultMap>
标签将两个表中的对象关联起来
分步骤联合查询 首先进行简单的N:1
联合查询,随后给出M:N
联合查询的解决方式
学生实体类 1 2 3 4 5 6 7 public class Student {private int id;private String name;private int age;private int tid;private Teacher teacher;}
TeacherMapper.xml 1 2 3 4 5 <mapper namespace ="com.test.mapper.TeacherMapper" > <select id ="selById" parameterType ="int" resultType ="Teacher" > select _ from teacher where id =#{0} </select > </mapper >
StudentMapper.xml 1 2 3 4 5 6 7 8 9 10 11 12 <mapper namespace ="com.test.mapper.StudentMapper" > <resultMap type ="Student" id ="stuMap" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="age" property ="age" /> <result column ="tid" property ="tid" /> <association property ="teacher" select ="com.test.mapper.TeacherMapper.selById" column ="tid" /> </resultMap > <select id ="selAll" resultMap ="stuMap" > select _ from student </select > </mapper >
装配对象时使用,其中 property 表示类中的属性名 select 表示要执行的 sql 语句,column 表示要传过去的字段参数
这种方式实现的细节就是:先一条 sql 查询出所有的学生,然后再查每个学生的学生,这是一种分布骤的方式,没有下面这种一次性的查找快捷
统一联合查询 StudentMapper.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <resultMap type ="Student" id ="stuMap1" > <id column ="sid" property ="id" /> <result column ="sname" property ="name" /> <result column ="sage" property ="age" /> <result column ="tid" property ="tid" /> <association property ="teacher" javaType ="teacher" > <id column ="tid" property ="id" /> <result column ="tname" property ="name" /> </association > </resultMap > <select id ="selAll1" resultMap ="stuMap1" > select s.id sid,s.name sname,s.age sage,t.id tid,t.name tname from student s left join teacher t on s.tid = t.id; </select >
查询关联集合对象 上面是N:1
解决方案,现在给出M:N
解决方案
教师实体类 1 2 3 4 5 public class Student {private int id;private String name;private List<Student> teacher;}
同样可以分步骤查询或者以统一查询,这里就直接给出统一查询的配置文件了
fileName 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <resultMap type ="Teacher" id ="teacMap1" > <id column ="tid" property ="id" /> <result column ="tname" property ="name" /> <collection property ="list" ofType ="Student" > <id column ="sid" property ="id" /> <result column ="sname" property ="name" /> <result column ="age" property ="age" /> <result column ="tid1" property ="tid" /> </collection > </resultMap > <select id ="selAll1" resultMap ="teacMap1" > select t.id tid, t.name tname, s.id sid, s.name sname,age ,s.tid tid1 from teacher t left join student s on t.id = s.tid </select >
附录 MyBatis 多表联合查询及优化 Mybatis 实现多表联查