在做电商类项目,例如淘宝,其app中的商品列表页面中,会有几个排序条件,例如价格、销量等。就像下面这个样子
如果用户点击“价格”,就是按照价格由低到高排序。
如果我们只使用同一个接口来处理商品列表数据的检索,那么mybatis中的sql,其order by就必须根据用户点选的“价格”、“销量”等条件进行排序。也就是说,order by 必须要做成活的,不能写死。
这里我们假设上面的商品列表页,用户一次只能点选一个排序条件。
ok, talk is cheap, show me the code.
<!-- 查询商户发布的商品信息 -->
<select id="getSalerGoodsList" parameterType="hashmap" resultType="java.util.HashMap">
SELECT
sgp.goodsId goodsId,
g.goodsTitle goodsName,
g.goodsTitle2 titleImage,
<!-- "价格"排序条件使用该字段 -->
CONVERT(sgp.retailPrice,DECIMAL(38,2)) retailPrice,
sgp.discount discount,
g.categoryName categoryName,
g.commodityUnit commodityUnit,
<!-- "综合"排序条件使用该字段 -->
sgp.publishTime publishTime,
<choose>
<!-- "人气"排序条件激活时,计算商品浏览量来进行排序 -->
<when test="null != orderBy and orderBy.indexOf('footprintCount') != -1">
(select count(ft.id) from ${customerGoodsFootprintTable} ft where ft.goodsId=sgp.goodsId) footprintCount,
</when>
<!-- "销量"排序条件激活时,计算商品成交量来进行排序 -->
<when test="null != orderBy and orderBy.indexOf('salesCount') != -1">
(select count(cao.id) from ${customerAtomOrderTable} cao where cao.goodsId=sgp.goodsId) salesCount,
</when>
</choose>
<!-- 商品“是否已收藏” -->
(select count(cfg.id) from ${customerFavoriteGoodsTable} cfg where sgp.goodsId=cfg.goodsId and cfg.customerId=#{customerId}) isFavoriteGoods
FROM
(
SELECT * FROM t_goods goods
<!-- “产地”、“口味”等可变属性搜索条件 -->
<if test="null != conditionList and conditionList.size()>0">
<where>
<foreach collection="conditionList" index="index" item="condition">
or goods.${condition.name} LIKE CONCAT('%','${condition.value}','%')
</foreach>
</where>
</if>
) g
INNER JOIN ${salerGoodsPublishTable} sgp ON g.id = sgp.goodsId
WHERE
sgp.status='1'
<if test="null != categoryId and categoryId != ''">
and g.categoryId LIKE CONCAT('%','${categoryId}','%')
</if>
<if test="null != goodsName and goodsName != ''">
and g.goodsTitle LIKE CONCAT('%','${goodsName}','%')
</if>
<if test="null != minPrice and minPrice != ''">
and sgp.retailPrice<![CDATA[>=]]>${minPrice}
</if>
<if test="null != maxPrice and maxPrice != ''">
and sgp.retailPrice<![CDATA[<=]]>${maxPrice}
</if>
<choose>
<when test="orderBy != null and orderBy!= ''">
order by ${orderBy}
</when>
<!-- 没有激活排序条件时,默认按商品发布时间倒序排序 -->
<otherwise>
order by publishTime desc
</otherwise>
</choose>
limit ${beginCurr},${pageSize}
</select>
上面的mybatis mapper文件中,如下的代码
<when test="null != orderBy and orderBy.indexOf('footprintCount') != -1">
是判断用户是否点选了某个排序条件。如果是按销量排序,则查询的字段中增加对商品销量的统计,然后在sql的最后将要排序的字段放到order by的后面。
如此这般,就可以针对用户点选的不同的排序条件,进行不同的处理。
当然,这个功能还有很多可以改进的空间,例如多个条件排序,可以自由指定某个字段升序或降序等等。其实我写这篇文章的重点就是记录一下在mybatis中,String类的一些操作,例如indexOf,valueOf也同样可以正常使用。当然,上面的sql写的实在是烂,大家将就着看吧。