1.1 多表关系
1.2 多表联合查询的sql语句
1.3 Mybatis关联查询的实现方式
使用单表查询,在业务层手动装配
采用多表联合查询,使用resultTpye自动装配
使用resultMap自动装配,又分为多表联合查询和单表N+1次查询
需求:查询所有学生和学生所在班级的信息
public class Cls {
private int id;
private String name;
}
public class Stu {
private int id;
private String name;
private int cid;
private Cls cls;
}
public interface StuMapper {
//查询全部学生
List<Stu> queryAll() throws Exception;
}
public interface ClsMapper {
//根据id查询数据
Cls queryById(int id) throws Exception;
}
<select id="queryAll" resultType="com.bodhixu.mybatis.bean.Stu">
select * from stu
select>
<select id="queryById" resultType="com.bodhixu.mybatis.bean.Cls" parameterType="int">
select * from cls where id = #{id}
select>
//① 查询所有学生的信息
List<Stu> stus = stuMapper.queryAll();
//② 遍历学生,根据学生的班级id,查询指定班级的信息
for (Stu stu : stus) {
Cls cls = clsMapper.queryById(stu.getCid());
stu.setCls(cls);
}
需求:查询所有学生和学生所在班级的信息
可以使用resultType属性,需要创建查询结果对应的实体类StuClsVo,然后查询语句中通过列别名对应结果实体类的属性。
public class StuClsVo {
private long sid; //学生编号
private String sname; //学生姓名
private long cid; //班级编号
private String cname; //班级名称
}
public interface StuClsMapper {
//查询全部学生班级信息
List<StuClsVo> queryAll();
}
<select id="queryAll" resultType="com.bodhixu.ssm.bean.StuClsVo">
select s.id sid, s.name sname, s.cid, c.name cname
from stu s
left join clse c
on s.cid = c.id
select>
resultMap的意思就是结果集映射,可以将一个复杂查询的结果映射到一个实体类上。
public class Stu {
private long sid;
private String name;
private Cls cls;
}
<resultMap type="com.bodhixu.mybatis.bean.Stu" id="stuClsResultMap">
<id column="sid" property="id"/>
<result column="name" property="name"/>
<association property="cls" javaType="com.bodhixu.mybatis.bean.Cls">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
association>
resultMap>
<select id="queryAll" resultMap="stuClsResultMap">
SELECT s.id sid, s.name, s.cid, c.name cname
FROM stu s
JOIN cls c
ON s.cid = c.id
select>
先查询学生信息,将学生的班级编号作为班级查询的参数
public class Stu {
private long sid;
private String name;
private Cls cls;
}
<resultMap type="com.bodhixu.mybatis.bean.Stu" id="stuClsMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="cls" select="com.bodhixu.mybatis.mapper.ClsMapper.queryById" column="cid">association>
resultMap>
<select id="queryAll" resultMap="stuClsMap">
select * from stu
select>
需求:查询所有班级和班级所属学生的信息
public class Stu {
private int id;
private String name;
private int cid;
}
public class Cls {
private int id;
private String name;
private List<Stu> stus;
}
public interface StuMapper {
//根据班级编号查询指定班级的学生
List<Stu> queryByCid(int cid) throws Exception;
}
public interface ClsMapper {
//查询全部数据
List<Cls> queryAll() throws Exception;
}
<select id="queryByCid" resultType="com.bodhixu.mybatis.bean.Stu" parameterType="int">
select * from stu where cid = #{cid}
select>
<select id="queryAll" resultType="com.bodhixu.mybatis.bean.Cls">
select * from cls
select>
//① 查询班级表,获得所有班级的集合
List<Cls> clses = clsMapper.queryAll();
//② 遍历班级集合,根据班级id,查询学生表获得当前班级下学生的集合
for (Cls cls : clses) {
//根据班级id,查询学生表获得当前班级下学生的集合
List<Stu> stus = stuMapper.queryByCid(cls.getId());
cls.setStus(stus);
}
public class Cls {
private long cid;
private String name;
private List<Stu> stus;
}
<resultMap type="com.bodhixu.mybatis.bean.Cls" id="clsStuMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="stus" ofType="com.bodhixu.mybatis.bean.Stu">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="id" property="cid"/>
collection>
resultMap>
<select id="queryAllClsStu" resultMap="clsStuMap">
SELECT c.id, c.name, s.id sid, s.name sname
FROM cls c
LEFT JOIN stu s
ON c.id = s.cid
select>
先查询班级信息,再将班级编号作为查询班级中学生信息的参数。
<resultMap type="com.bodhixu.mybatis.bean.Cls" id="clsStuMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="stus" ofType="com.bodhixu.mybatis.bean.Stu"
select="com.bodhixu.mybatis.mapper.StuMapper.queryByCid" column="id">
collection>
resultMap>
<select id="queryAllClsStu" resultMap="clsStuMap">
select * from cls
select>