多对一查询
- 关联方式查询
例:
通过多表关联的SQL语法进行查询, 需要使用join, on, …来实现查询. 执行一条SQL语句就可以将所有需要的数据全部查询到. 我们需要做的就是将查到的数据进行映射即可.
StudentMapper.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.bjsxt.mapper.StudentMapper">
<resultMap id="smap" type="student" autoMapping="true">
<!--<id column="id" property="id" />
<result column="name" property="name" />
<result column="gender" property="gender" />
<result column="birthday" property="birthday" />-->
<!--关联单个对象要使用association-->
<association property="clazz" javaType="clazz" autoMapping="true">
<id column="cid" property="id" />
<result column="cname" property="name" />
<!--<result column="room" property="room" />-->
</association>
</resultMap>
<select id="selAll" resultMap="smap">
select
s.*, c.name cname, c.room
from
tb_student s
left join
tb_class c
on
s.cid = c.id
</select>
</mapper>
- N+1方式查询
表示所有数据要获取到需要执行N+1条SQL语句. 每次查询都是单表查询, 查多次就拿到所有数据了.
例:
StudentMapper.xml:
<resultMap id="smap2" type="student">
<!--映射单个对象-->
<association
property="clazz"
javaType="clazz"
select="com.bjsxt.mapper.ClazzMapper.selById"
column="cid" />
</resultMap>
<select id="selAll2" resultMap="smap2">
select * from tb_student
</select>
ClazzMapper.xml:
<mapper namespace="com.bjsxt.mapper.ClazzMapper">
<select id="selById" resultType="clazz">
select * from tb_class where id=#{id}
</select>
</mapper>
一对多查询
关联查询:
<resultMap id="cmap" type="clazz" autoMapping="true">
<!--关联集合对象, 使用collection标签-->
<collection property="students" javaType="list" ofType="student" autoMapping="true">
<id column="sid" property="id" />
<result column="sname" property="name" />
</collection>
</resultMap>
<select id="selAll" resultMap="cmap">
select
c.*, s.id sid, s.name sname, s.gender, s.birthday
from
tb_class c
left join
tb_student s
on
c.id = s.cid
</select>
N+1查询
StudentMapper.xml:
<resultMap id="cmap2" type="clazz">
<!--如果这一列作为参数继续传递, 会导致自动映射失败-->
<id column="id" property="id" />
<collection
property="students"
javaType="list"
ofType="student"
select="com.bjsxt.mapper.StudentMapper.selByCid"
column="id" />
</resultMap>
<select id="selAll2" resultMap="cmap2">
select * from tb_class
</select>
ClazzMapper.xml:
<mapper namespace="com.bjsxt.mapper.StudentMapper">
<select id="selByCid" resultType="student">
select * from tb_student where cid=#{cid}
</select>
</mapper>
业务装配方式查询
EmpMapper.xml
<select id="selAll" resultType="emp">
select * from tb_emp
</select>
@Test
public void test2() {
SqlSession session = MyBatisUtil.getSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
List<Emp> list = mapper.selAll();
// 将平级结构转换为树状结构 -- 业务装配
List<Emp> tree = list2Tree(list);
System.out.println(tree);
session.close();
}
private List<Emp> list2Tree(List<Emp> dataList) {
List<Emp> result = new ArrayList<>();
// 将list集合转换为Map集合, 方便查出领导使用
Map<Integer, Emp> temp = new HashMap<>();
for (Emp emp : dataList) {
temp.put(emp.getEmpno(), emp);
}
// 结构转换
for (Emp emp : dataList) {
// 判断当前员工是不是顶级员工(总裁)
if(emp.getMgr() == null) {
result.add(emp);
continue;
}
// 普通员工, 找上级领导
temp.get(emp.getMgr()).getEmps().add(emp);
}
return result;
}
关联查询和N+1查询对比
a) 关联查询:
- sql语句是关联语法, 需要使用join…on…
- 只需要执行1条SQL语句
- 默认情况下, 不会自动映射, 可以通过设置autoMapping=true开启自动映射
b) N+1查询:
-
SQL语句都是单表查询
-
需要执行N+1次查询才能得到结果
-
默认情况下, 就会自动映射.