我们都知道对于简单的一对多查询,我们可以先将一的全部属性查询出来,然后再通过第二次查询将多端也查询出来,这样做通过两条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
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;
- }
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的出现。不知道大家有没有注意到上面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>
-
-
- <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表示集合泛型内部的属性类型。
返回结果: