我们都知道对于简单的一对多查询,我们可以先将一的全部属性查询出来,然后再通过第二次查询将多端也查询出来,这样做通过两条SQL语句通俗易懂,但是有没有办法通过一条SQL语句直接返回一对多的查询结果呢?
模型说明:
一个Banner 内部包含多个BannerItem,最终我们要根据Banner的name来查询出Banner的属性以及该Banner包含的所有BannerItem
模型类:
//最终要返回的类:
@Data
@NoArgsConstructor
public class BannerByNameVo {
private Long id;
private String name;
private String description;
private String title;
private String img;
private List<BannerItem> items;
}
//BannerItem类:
@Data
public class BannerItem implements Serializable {
private Long id;
private String img;
private String keyword;
private Short type;
private Integer bannerId;
private String name;
}
XML文件部分:
1、查询语句部分
<select id="selectByNames" resultType="List">
select *
from banner b
join banner_item bi on bi.banner_id = b.id
where b.name = #{name};
</select>
当我们直接将上述SQL语句放到MySQL中运行时,会给我们返回:(数据库中该Banner有3个BannerItem属性)
将二者的所有列都返回,但是Banner部分的数据列数值全部一样,不一样的只是BannerItem部分列的属性值。这是因为SQL只能通过这种方式来为我们返回属性值。
ResaultMap:
针对上述问题我们就想能不能将相同部分保存下来,将不同部分保存到一个数组中,于是有了ResaultMap的出现。不知道大家有没有注意到上面SQL语句中的ResultType属性,其实二者的性质是相同的,所以不能同时出现,都表示返回的数据类型。
所以针对上述代码我们可以这样修改:
<!--结果集映射-->
<resultMap autoMapping="true" id="bannerAndBannerItems" type="com.lin.missyou.vo.BannerByNameVo">
<id column="id" property="id" javaType="java.lang.Long"/>
<collection autoMapping="true" property="items" ofType="com.lin.missyou.repository.pojo.BannerItem">
<id column="bid" property="id"/>
<result property="img" column="bimg"/>
<result property="name" column="bname"/>
</collection>
</resultMap>
<!--SQL语句部分-->
<select id="selectByNames" resultMap="bannerAndBannerItems">
select b.*,
bi.*,
bi.id bid,
bi.img bimg,
bi.name bname
from banner b
join banner_item bi on bi.banner_id = b.id
where b.name = #{name};
</select>
1、我们通过ResultMap指明数据的返回类型。
2、每个内部都要写好Id属性。
3、collection标签表示集合属性
4、result表示返回的结果映射。通常用于别名情况。
5、autoMapping让属性值自动匹配。数据库的列与实体类中自动进行字段映射,当数据库中的字段无法与实体类中的字段进行匹配的时候就要用result来进行映射。
6、自动映射的前提是查询的结果集无重复字段。针对上面的查询,我们发现BannerByNameVO中有id、img、name字段,但是BannerItem中也有相同的字段,所以针对这种字段必须进行result映射,否则就会用前面的值替换后面的值。所以上述代码采用了起别名的方式进行名称的替换。
7、column是数据库查询出来的字段名,如果使用了as别名,则表示别名名称。
8、property属性表示实体类中的属性名。
9、ofType表示集合泛型内部的属性类型。
返回结果: