实战SSM_O2O商铺_41【前端展示】店铺列表页面Dao+Service+Controller层的实现

简介: 实战SSM_O2O商铺_41【前端展示】店铺列表页面Dao+Service+Controller层的实现

概述


在完成了首页轮播图和首页商品分类的展示之后,


20180803202635356.png

按照页面原型设计

  • 点击全部商店后加载一级商铺列表,加载对应的数据
  • 点击特定的一级商铺列表,加载对应商铺列表下的数据
  • 区域显示全部区域
  • 店铺列表页面需要支持分页功能,使用无极滚动的样式
  • 店铺列表页面需要支持多条件排列组合查询店铺信息

如下


20180808205101517.png


Dao层

接口

复用ShopDao#selectShopList方法

  List<Shop> selectShopList(@Param("shopCondition") Shop shopCondition, @Param("rowIndex") int rowIndex, @Param("pageSize") int pageSize);


映射文件

增加如下查询条件,满足当用户点击某个一级商铺类别的时候,加载改商铺类别下全部的商铺。

  <!-- 选择了某个大类,列举出该大类下面的全部商店   以parent_id来筛选  -->
    <if test="shopCondition.shopCategory != null 
      and shopCondition.shopCategory.parent != null
      and shopCondition.shopCategory.parent.shopCategoryId != null ">
      and s.shop_category_id in (
        select shop_category_id 
          from  tb_shop_category 
          where parent_id =  #{shopCondition.shopCategory.parent.shopCategoryId}
        )
    </if>


单元测试


表中的数据


20180804114638846.png


@Test
  public void testSelectShopListAndCount2() {
    // 根据表中的数据 共计6条数据
    // 其中 2条 属于 【咖啡】二级商铺类别
    // 其中 2条 属于 【奶茶】二级商铺类别
    // 其中 2条 属于 【考研辅导】二级商铺类别
    // 而 【咖啡】和【奶茶】二级商铺类别 属于 【美食饮品】一级商铺类别
    // 模拟用户点击【美食饮品】,查询出来属于 【美食饮品】下面的商铺 ,
    // 期望符合条件的数据为 2条 属于 【咖啡】二级商铺类别的店铺 + 2条 属于 【奶茶】二级商铺类别 的店铺
    /**
     * 
     * <!-- 选择了某个大类,列举出该大类下面的全部商店 以parent_id来筛选 --> <if
     * test="shopCondition.shopCategory != null and
     * shopCondition.shopCategory.parent != null and
     * shopCondition.shopCategory.parent.shopCategoryId != null "> and
     * s.shop_category_id in ( select shop_category_id from tb_shop_category
     * where parent_id = #{shopCondition.shopCategory.parent.shopCategoryId}
     * ) </if>
     * 
     * 
     * 
     */
    Shop shopCondition = new Shop();
    // 模拟
    ShopCategory childShopCategory = new ShopCategory();
    ShopCategory parentShopCategory = new ShopCategory();
    // 设置父类的shopCategoryId
    parentShopCategory.setShopCategoryId(3L);
    // 设置父子关系
    childShopCategory.setParent(parentShopCategory);
    // 设置目录
    shopCondition.setShopCategory(childShopCategory);
    List<Shop> shoplist = shopDao.selectShopList(shopCondition, 0, 5);
    int count = shopDao.selectShopCount(shopCondition);
    Assert.assertEquals(4, shoplist.size());
    Assert.assertEquals(4, count);
    for (Shop shop : shoplist) {
      System.out.println(shop.toString());
    }
  }

20180804114529581.png

日志

==>  Preparing: SELECT s.shop_id, s.shop_name, s.shop_desc, s.shop_addr, s.phone, s.shop_img, s.priority, s.create_time, s.last_edit_time, s.enable_status, s.advice, a.area_id, a.area_name, sc.shop_category_id, sc.shop_category_name FROM tb_shop s, tb_area a, tb_shop_category sc WHERE s.shop_category_id in ( select shop_category_id from tb_shop_category where parent_id = ? ) AND s.area_id = a.area_id AND s.shop_category_id = sc.shop_category_id ORDER BY s.priority DESC LIMIT ? , ? 
Sat Aug 04 11:44:36 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sat Aug 04 11:44:36 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
==> Parameters: 3(Long), 0(Integer), 5(Integer)
<==    Columns: shop_id, shop_name, shop_desc, shop_addr, phone, shop_img, priority, create_time, last_edit_time, enable_status, advice, area_id, area_name, shop_category_id, shop_category_name
<==        Row: 4, 咖啡店1, 咖啡店1简介, 东方明珠, 1234, \upload\item\shopImage\4\2018072718443825588.jpg, 99, 2018-07-27 10:44:39, 2018-07-27 10:44:39, 1, null, 2, 上海, 7, 咖啡
<==        Row: 5, 咖啡店2, 咖啡店2简介, 上海某地, 123456, \upload\item\shopImage\5\2018080410065694536.jpg, 98, 2018-08-04 02:06:56, 2018-08-04 02:35:51, 1, Waring UP, 2, 上海, 7, 咖啡
<==        Row: 6, 奶茶店1, 奶茶店1简介, 东直门, 654321, \upload\item\shopImage\6\2018080410074110364.jpg, 97, 2018-08-04 02:07:42, 2018-08-04 02:07:42, 1, null, 1, 北京, 9, 奶茶
<==        Row: 7, 奶茶店2, 奶茶店2简介, 798艺术区, 56789, \upload\item\shopImage\7\2018080410094723088.jpg, 96, 2018-08-04 02:09:48, 2018-08-04 02:09:48, 1, null, 1, 北京, 9, 奶茶
<==      Total: 4
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@78641d23]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2c1156a7] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@691939c9] will not be managed by Spring
==>  Preparing: SELECT count(1) FROM tb_shop s, tb_area a, tb_shop_category sc WHERE s.shop_category_id in ( select shop_category_id from tb_shop_category where parent_id = ? ) AND s.area_id = a.area_id AND s.shop_category_id = sc.shop_category_id 
==> Parameters: 3(Long)
<==    Columns: count(1)
<==        Row: 4
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2c1156a7]
Shop [shopId=4, shopName=咖啡店1, shopDesc=咖啡店1简介, shopAddr=东方明珠, phone=1234, shopImg=\upload\item\shopImage\4\2018072718443825588.jpg, priority=99, createTime=Fri Jul 27 18:44:39 CST 2018, lastEditTime=Fri Jul 27 18:44:39 CST 2018, enableStatus=1, advice=null, owner=null, area=Area [areaId=2, areaName=上海, areaDesc=null, priority=null, createTime=null, lastEditTime=null], shopCategory=ShopCategory [shopCategoryId=7, shopCategoryName=咖啡, shopCategoryDesc=null, shopCategoryImg=null, priority=null, createTime=null, lastEditTime=null, parent=null]]
Shop [shopId=5, shopName=咖啡店2, shopDesc=咖啡店2简介, shopAddr=上海某地, phone=123456, shopImg=\upload\item\shopImage\5\2018080410065694536.jpg, priority=98, createTime=Sat Aug 04 10:06:56 CST 2018, lastEditTime=Sat Aug 04 10:35:51 CST 2018, enableStatus=1, advice=Waring UP, owner=null, area=Area [areaId=2, areaName=上海, areaDesc=null, priority=null, createTime=null, lastEditTime=null], shopCategory=ShopCategory [shopCategoryId=7, shopCategoryName=咖啡, shopCategoryDesc=null, shopCategoryImg=null, priority=null, createTime=null, lastEditTime=null, parent=null]]
Shop [shopId=6, shopName=奶茶店1, shopDesc=奶茶店1简介, shopAddr=东直门, phone=654321, shopImg=\upload\item\shopImage\6\2018080410074110364.jpg, priority=97, createTime=Sat Aug 04 10:07:42 CST 2018, lastEditTime=Sat Aug 04 10:07:42 CST 2018, enableStatus=1, advice=null, owner=null, area=Area [areaId=1, areaName=北京, areaDesc=null, priority=null, createTime=null, lastEditTime=null], shopCategory=ShopCategory [shopCategoryId=9, shopCategoryName=奶茶, shopCategoryDesc=null, shopCategoryImg=null, priority=null, createTime=null, lastEditTime=null, parent=null]]
Shop [shopId=7, shopName=奶茶店2, shopDesc=奶茶店2简介, shopAddr=798艺术区, phone=56789, shopImg=\upload\item\shopImage\7\2018080410094723088.jpg, priority=96, createTime=Sat Aug 04 10:09:48 CST 2018, lastEditTime=Sat Aug 04 10:09:48 CST 2018, enableStatus=1, advice=null, owner=null, area=Area [areaId=1, areaName=北京, areaDesc=null, priority=null, createTime=null, lastEditTime=null], shopCategory=ShopCategory [shopCategoryId=9, shopCategoryName=奶茶, shopCategoryDesc=null, shopCategoryImg=null, priority=null, createTime=null, lastEditTime=null, parent=null]]
八月 04, 2018 11:44:37 上午 org.springframework.context.support.GenericApplicationContext doClose



Service层

接口方法

复用ShopService#getShopList

##接口实现类

ShopServiceImpl#getShopList


单元测试

因复用,之前已经单元测试通过,这里省略。


Controller层

增加 ShopListController

package com.artisan.o2o.web.frontend;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.artisan.o2o.dto.ShopExecution;
import com.artisan.o2o.entity.Area;
import com.artisan.o2o.entity.Shop;
import com.artisan.o2o.entity.ShopCategory;
import com.artisan.o2o.service.AreaService;
import com.artisan.o2o.service.ShopCategoryService;
import com.artisan.o2o.service.ShopService;
import com.artisan.o2o.util.HttpServletRequestUtil;
@Controller
@RequestMapping("/frontend")
public class ShopListController {
  @Autowired
  private ShopService shopService;
  @Autowired
  private AreaService areaService;
  @Autowired
  private ShopCategoryService shopCategoryService;
  @RequestMapping(value = "/listshopspageinfo", method = RequestMethod.GET)
  @ResponseBody
  private Map<String, Object> listShopsPageInfo(HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    long parentId = HttpServletRequestUtil.getLong(request, "parentId");
    List<ShopCategory> shopCategoryList = null;
    // parentId不为空,查询出对应parentId目录下的全部商品目录
    if (parentId != -1) {
      try {
        ShopCategory childCategory = new ShopCategory();
        ShopCategory parentCategory = new ShopCategory();
        parentCategory.setShopCategoryId(parentId);
        childCategory.setParent(parentCategory);
        shopCategoryList = shopCategoryService.getShopCategoryList(childCategory);
      } catch (Exception e) {
        modelMap.put("success", false);
        modelMap.put("errMsg", e.toString());
      }
    } else {
      // parentId为空,查询出一级的shopCategory
      try {
        shopCategoryList = shopCategoryService.getShopCategoryList(null);
      } catch (Exception e) {
        modelMap.put("success", false);
        modelMap.put("errMsg", e.toString());
      }
    }
    modelMap.put("shopCategoryList", shopCategoryList);
    List<Area> areaList = null;
    try {
      areaList = areaService.getAreaList();
      modelMap.put("areaList", areaList);
      modelMap.put("success", true);
      return modelMap;
    } catch (Exception e) {
      modelMap.put("success", false);
      modelMap.put("errMsg", e.toString());
    }
    return modelMap;
  }
  @RequestMapping(value = "/listshops", method = RequestMethod.GET)
  @ResponseBody
  private Map<String, Object> listShops(HttpServletRequest request) {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    int pageIndex = HttpServletRequestUtil.getInt(request, "pageIndex");
    int pageSize = HttpServletRequestUtil.getInt(request, "pageSize");
    if ((pageIndex > -1) && (pageSize > -1)) {
      long parentId = HttpServletRequestUtil.getLong(request, "parentId");
      long shopCategoryId = HttpServletRequestUtil.getLong(request, "shopCategoryId");
      int areaId = HttpServletRequestUtil.getInt(request, "areaId");
      String shopName = HttpServletRequestUtil.getString(request, "shopName");
      // 封装查询条件
      Shop shopCondition = compactShopCondition4Search(parentId, shopCategoryId, areaId, shopName);
      // 调用service层提供的方法
      ShopExecution se = shopService.getShopList(shopCondition, pageIndex, pageSize);
      modelMap.put("shopList", se.getShopList());
      modelMap.put("count", se.getCount());
      modelMap.put("success", true);
    } else {
      modelMap.put("success", false);
      modelMap.put("errMsg", "empty pageSize or pageIndex");
    }
    return modelMap;
  }
  private Shop compactShopCondition4Search(long parentId, long shopCategoryId, int areaId, String shopName) {
    Shop shopCondition = new Shop();
    if (parentId != -1L) {
      ShopCategory childCategory = new ShopCategory();
      ShopCategory parentCategory = new ShopCategory();
      parentCategory.setShopCategoryId(parentId);
      childCategory.setParent(parentCategory);
      shopCondition.setShopCategory(childCategory);
    }
    if (shopCategoryId != -1L) {
      ShopCategory shopCategory = new ShopCategory();
      shopCategory.setShopCategoryId(shopCategoryId);
      shopCondition.setShopCategory(shopCategory);
    }
    if (areaId != -1L) {
      Area area = new Area();
      area.setAreaId(areaId);
      shopCondition.setArea(area);
    }
    if (shopName != null) {
      shopCondition.setShopName(shopName);
    }
    // 查询状态为审核通过的商铺
    shopCondition.setEnableStatus(1);
    return shopCondition;
  }
}


单元测试

启动tomcat,可以以debug的方式调测

分别对两个路由方法进行测试类,访问如下URL

http://localhost:8080/o2o/frontend/listshopspageinfo
http://localhost:8080/o2o/frontend/listshopspageinfo?parentId=5


http://localhost:8080/o2o/frontend/listshops?pageIndex=1&pageSize=3
http://localhost:8080/o2o/frontend/listshops?pageIndex=1&pageSize=3&parentId=3
http://localhost:8080/o2o/frontend/listshops?pageIndex=1&pageSize=3&parentId=3&shopName=咖啡

观察返回的json数据,是否符合预期。


Github地址

代码地址: https://github.com/yangshangwei/o2o

相关文章
|
搜索推荐 JavaScript Java
计算机Java项目|基于SSM的个性化商铺系统
计算机Java项目|基于SSM的个性化商铺系统
106 1
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的商铺租赁管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的商铺租赁管理系统附带文章和源代码部署视频讲解等
157 7
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
|
SQL 测试技术
实战SSM_O2O商铺_32【商品】商品编辑之Dao层的实现
实战SSM_O2O商铺_32【商品】商品编辑之Dao层的实现
108 0
|
11月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
834 14
|
11月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
202 0
|
11月前
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
325 6
|
12月前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
11月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
418 1