MyBatis的多表联合查询

时间:2022-11-06 00:24:25

1注意事项: 当多表联合查询的时候,出现重复的属性名称,要给属性添加对应的前缀.

2写博客原因: 遇到这个需求,网上找了好久,虽然找到方法了,但是花了很长的时间,中间还遇到了一个特别棘手的问题,(也算我自己太大意了)

表 1-多的情况,可以使用myBatis的关联查询查询出来,
一对多的情况,在一的那张表中,添加:

<collection property="adImagePaths" ofType="com.htmob.crm.model.AdImagePath">
<id column="adImagePaths.id" jdbcType="INTEGER" property="id"/>
<result column="adImagePaths.material_id" jdbcType="INTEGER" property="materialId"/>
<result column="adImagePaths.image_url" jdbcType="VARCHAR" property="imageUrl"/>
</collection>

` 同样;可以添加

<collection property="adImagePaths" resultMap="命名空间 + 属性配置名"

以下用第一种方法:
我给原来那张多的表的每个字段名称添加了一个表的前缀,读者可以不添加,我添加的原因的,我查询出来的2表的所有属性,但是这2张表存在属性名称一样的情况,所有会出现,系统不知道怎么匹配的问题,所有我给每个字段添加了一个前坠的名称….

select m.*,p.* from crm.ad_material m left join crm.ad_position p on p.id = m.ad_id; 

“or

select m.*,p.* from crm.ad_image_path p left join crm.ad_material m on m.id = p.material_id 

都可以查询出来结果;
完整的配置如下:

<resultMap id="BaseResultMap" type="com.htmob.crm.model.AdMaterial">
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
-->

<id column="id" jdbcType="INTEGER" property="id"/>
<result column="user_id" jdbcType="INTEGER" property="userId"/>
<result column="media_source" jdbcType="VARCHAR" property="mediaSource"/>
<result column="examine" jdbcType="VARCHAR" property="examine"/>
<result column="examine_result" jdbcType="VARCHAR" property="examineResult"/>
<result column="label" jdbcType="VARCHAR" property="label"/>
<result column="download" jdbcType="INTEGER" property="download"/>
<result column="ad_id" jdbcType="INTEGER" property="adId"/>

<!--一对多的配置-->
<!--<collection property="adImagePaths" resultMap="com.htmob.crm.dao.AdImagePathMapper.BaseResultMap">-->
<!--</collection>-->
<collection property="adImagePaths" ofType="com.htmob.crm.model.AdImagePath">
<id column="adImagePaths.id" jdbcType="INTEGER" property="id"/>
<result column="adImagePaths.material_id" jdbcType="INTEGER" property="materialId"/>
<result column="adImagePaths.image_url" jdbcType="VARCHAR" property="imageUrl"/>
</collection>

</resultMap>



` 如果 你想在上面一对多的表中,配置好了,但是这个一对多的表中的那个一,有他对应的一对多的其他表,这个个关系中,他属于多,

`你想在这个一种,获取上一级的表的属性,:

`

<!--广告位 关联-->
<association property="adPosition" javaType="com.htmob.crm.model.AdPosition">
<id column="adPosition.id" jdbcType="INTEGER" property="id"/>
<result column="adPosition.ad_name" jdbcType="VARCHAR" property="adName"/>
<result column="adPosition.media_source" jdbcType="VARCHAR" property="mediaSource"/>
<result column="adPosition.platform" jdbcType="INTEGER" property="platform"/>
<result column="adPosition.width" jdbcType="INTEGER" property="width"/>
<result column="adPosition.height" jdbcType="INTEGER" property="height"/>
<result column="adPosition.image_num" jdbcType="INTEGER" property="imageNum"/>
<result column="adPosition.image_type" jdbcType="VARCHAR" property="imageType"/>
</association>

同样可以用命名空间来处理上面这段代码;
完整的如下:

    <resultMap id="BaseResultMap" type="com.htmob.crm.model.AdMaterial">
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
-->

<id column="id" jdbcType="INTEGER" property="id"/>
<result column="user_id" jdbcType="INTEGER" property="userId"/>
<result column="media_source" jdbcType="VARCHAR" property="mediaSource"/>
<result column="examine" jdbcType="VARCHAR" property="examine"/>
<result column="examine_result" jdbcType="VARCHAR" property="examineResult"/>
<result column="label" jdbcType="VARCHAR" property="label"/>
<result column="download" jdbcType="INTEGER" property="download"/>
<result column="ad_id" jdbcType="INTEGER" property="adId"/>

<!--广告位 关联-->
<association property="adPosition" javaType="com.htmob.crm.model.AdPosition">
<id column="adPosition.id" jdbcType="INTEGER" property="id"/>
<result column="adPosition.ad_name" jdbcType="VARCHAR" property="adName"/>
<result column="adPosition.media_source" jdbcType="VARCHAR" property="mediaSource"/>
<result column="adPosition.platform" jdbcType="INTEGER" property="platform"/>
<result column="adPosition.width" jdbcType="INTEGER" property="width"/>
<result column="adPosition.height" jdbcType="INTEGER" property="height"/>
<result column="adPosition.image_num" jdbcType="INTEGER" property="imageNum"/>
<result column="adPosition.image_type" jdbcType="VARCHAR" property="imageType"/>
</association>

<!--一对多的配置-->
<!--<collection property="adImagePaths" resultMap="com.htmob.crm.dao.AdImagePathMapper.BaseResultMap">-->
<!--</collection>-->
<collection property="adImagePaths" ofType="com.htmob.crm.model.AdImagePath">
<id column="adImagePaths.id" jdbcType="INTEGER" property="id"/>
<result column="adImagePaths.material_id" jdbcType="INTEGER" property="materialId"/>
<result column="adImagePaths.image_url" jdbcType="VARCHAR" property="imageUrl"/>
</collection>

</resultMap>

`三张表的查询语句.
select m.,img. from crm.ad_image_path img left join crm.ad_material m on m.id=img.material_id
left join crm.ad_position po on po.id = m.ad_id


`比如我是这么写的:


<select id="selectFromShowData" resultMap="BaseResultMap" parameterType="com.model.AdMaterialData">
select m.*,
img.id as "adImagePaths.id",
img.material_id as "adImagePaths.material_id",
img.image_url as "adImagePaths.image_url",
po.ad_name as "adPosition.ad_name",
po.width as "adPosition.width",
po.height as "adPosition.height",
po.image_num as "adPosition.image_num",
po.image_type as "adPosition.image_type"
from ad_image_path img
left join ad_material m on m.id=img.material_id
left join ad_position po on po.id = m.ad_id
where
<trim>
<if test="platFrom != null and platFrom != -1">
po.platform = #{platFrom,jdbcType=INTEGER} and
</if>
<if test="adOrderUserId != null and platFrom != -1">
m.user_id = #{adOrderUserId,jdbcType=INTEGER} and
</if>
<if test="adPositionId != null and adPositionId != -1">
m.ad_id = #{adPositionId,jdbcType=INTEGER} and
</if>
<if test="mediaSource != null and mediaSource != ''">
m.media_source = #{mediaSource,jdbcType=VARCHAR} and
</if>
<if test="label != null and label != ''">
m.label LIKE #{label,jdbcType=VARCHAR} and
</if>
</trim>
m.id is not NULL and img.id is not null
</select>

`其中: com.model.AdMaterialData 是:

public class AdMaterialData implements Serializable {
// 查询 adMaterial 表的字段

private int platFrom; // position表 中 查询
private int adOrderUserId; // 广告位id
private int adPositionId; // 对应广告位的id
private String mediaSource;
private String label;

private int id;
// set and get method write
}

`BaseResultMap是自身的属性,就是上面的那个完整的<resultMap ...>