1: 一对多分页查询
当一对多用<connection>标签时,如果是详情查询可以直接使用,但如果是列表分页时则会出现每页条数错误的问题,原因在于:一对多时,分页数量统计的是这里的多的总数,比如每页10条数据,列表只有5条,原因是这5条每条对应2条子集数据,所以需要用嵌套子查询,记录代码如下:
<resultMap id="listModel" type="com.elementwin.common.model.vo.SpeechcraftContentDetailVO">
<id column="id" property="id" />
<result column="structId" property="structId"/>
<result column="custCategory" property="custCategory"/>
<result column="rfmLife" property="rfmLife"/>
<result column="star" property="star"/>
<result column="title" property="title"/>
<result column="top" property="top"/>
<result column="updateTime" property="updateTime"/>
<result column="displayArea" property="displayArea"/>
<result column="businessType" property="businessType"/>
<result column="useType" property="useType"/>
<result column="orgName" property="orgName"/>
<result column="updateByName" property="updateByName"/>
<!-- 这里即为嵌套子查询,id和carModelId都是取的主查询结果字段,作为参数传给子查询使用-->
<collection property="carModelList" ofType="com.elementwin.common.model.SpeechcraftContentCarRel" select="queryListModel" column="{id=id, carModelId=carModelId}">
</collection>
</resultMap>
<!-- 列表查询 -->
<select id="pageList" resultMap="listModel">
select
sc.id, sc.struct_id as structId, sc.cust_category as custCategory, sc.rfm_life as rfmLife, sc.star, sc.title, sc.top,
date_format(sc.update_time,'%Y-%m-%d %H:%i:%S') as updateTime,
ss.display_area as displayArea,
pe.business_type as businessType, pe.use_type as useType,
o.short_name as orgName,
upu.realname AS updateByName,
<!-- 这里取的是接口入参传进来的参数,非查询结果需要,是虚拟参数,用来传给子查询作为参数使用-->
IFNULL(#{query.carModelId}, '') AS carModelId
from
speechcraft_struct_content sc
left join
speechcraft_struct ss on sc.struct_id = ss.id
left join
speechcraft pe on ss.speech_id = pe.id
left join
organization o on pe.org_id = o.id
left join
user upu on upu.id = sc.update_by
where
sc.active = 1
and
ss.active = 1
and
pe.active = 1
<if test="query.structId == null or query.structId == ''">
and
struct_id in
<foreach collection="structIds" item="structId" open="(" separator="," close=")">
#{structId}
</foreach>
</if>
<if test="query.title != null and query.title != ''">
and sc.title like concat('%', #{query.title}, '%')
</if>
<!-- 因为主表数据是需要符合查询条件的分页数量,所以这里主表是需要先根据条件进行筛选,主表的id筛选结果必须是 符合子表中的查询结果 -->
<if test="query.carModelId != null and query.carModelId != ''">
and sc.id in (select content_id from speechcraft_content_car_rel where car_model_id = #{query.carModelId})
</if>
order by
sc.update_time desc,
sc.create_time desc
<if test="page != null">
limit #{page.begin}, #{page.pageSize}
</if>
</select>
<!-- 子查询 -->
<select id="queryListModel" resultType="com.elementwin.common.model.SpeechcraftContentCarRel">
select
car.content_id AS contentId, car.car_model_id AS carModelId, d.name AS carName
from
speechcraft_content_car_rel car
left join
car_data d on car.car_model_id = d.id
where
car.content_id = #{id}
<!-- 下面这个where条件是不需要的,放在这里的原因是为了呈现,carModelId也是传进来的参数可以使用 -->
<!--==<where>
car.content_id = #{id}
<if test="carModelId != null and carModelId != ''">
and car.content_id in (select content_id from speechcraft_content_car_rel where car_model_id = #{carModelId})
</if>
</where>-->
</select>
功能需要实现:
列表数据分页,主表数据关联子表,结果呈现是以主表分页,其中一对多包含多个子表数据,并且子表中的字段值也作为判断依据。
代码位于yuanbing公司management项目:com.elementwin.common.service.mapper.SpeechcraftStructContentMapper#pageList
2: 用判断等构造出一个查询字段用于sql使用
<select id="contentPageList" parameterType="com.elementwin.common.model.dto.PageParam" resultType="com.elementwin.common.model.speechcraft.dto.SpeechcraftContentDTO">
SELECT content.struct_id structId,struct.parent_id as structParentId, content.id, content.title, content.star,
case when
(content.top = 1 and #{model.currentTime} BETWEEN content.top_begin_time AND content.top_end_time) then 1
else 0
end AS top
FROM speechcraft_struct_content content
LEFT JOIN speechcraft_struct struct ON struct.id = content.struct_id
LEFT JOIN speechcraft self ON self.id = struct.speech_id
<where>
<include refid="contentSearchQueryVO"></include>
</where>
ORDER BY top desc, content.top_begin_time desc, content.update_time desc, struct.parent_id ASC, struct.sort ASC, content.create_time DESC
<choose>
<when test="begin != null">
LIMIT #{begin}, #{pageSize}
</when>
</choose>
</select>
列表查询出的每一列数据,当查询出的这列结果中content.top=1并且传进来的时间在top_begin_time和top_end_time之间,则为1,否则为0,并取别名为top。
作用有2个:
一个是业务需要,需求是本来top为1就是置顶,但是搜索的时候是否置顶还有一个条件,当前时间并且必须在置顶开始时间和结束之间才显示为置顶。所以,这里查询用了case when
二个是通过构造的这个查询列可以作为下面sql其他判断等语句使用,比如这里就作为排序使用
备注:可以有多个case when。
代码位于yuanbing公司business项目:com.elementwin.common.service.mapper.SpeechcraftMapper#contentPageList