实战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

相关文章
|
20天前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
159 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
14天前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
47 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
17天前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
36 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
1月前
|
Dart 前端开发 容器
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
86 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
15天前
|
存储 Java 关系型数据库
ssm026校园美食交流系统(文档+源码)_kaic
本文介绍了基于Java语言和MySQL数据库的校园美食交流系统的设计与实现。该系统采用B/S架构和SSM框架,旨在提高校园美食信息管理的效率与便捷性。主要内容包括:系统的开发背景、目的及内容;对Java技术、MySQL数据库、B/S结构和SSM框架的介绍;系统分析部分涵盖可行性分析、性能分析和功能需求分析;最后详细描述了系统各功能模块的具体实现,如登录、管理员功能(美食分类管理、用户管理等)和前台首页功能。通过此系统,管理员可以高效管理美食信息,用户也能方便地获取和分享美食资讯,从而提升校园美食交流的管理水平和用户体验。
|
8天前
|
存储 Java 关系型数据库
ssm064农产品仓库管理系统系统(文档+源码)_kaic
农产品仓库管理系统基于现代经济快速发展和信息化技术的升级,采用SSM框架、Java语言及Mysql数据库开发。系统旨在帮助管理者高效处理大量数据信息,提升事务处理效率,实现数据管理的科学化与规范化。该系统涵盖物资基础数据管理、出入库订单管理等功能,界面简洁美观,符合用户操作习惯,并提供数据安全解决方案,确保信息的安全性和可靠性。通过自动化和集中处理,系统显著提高了仓库管理的效率和准确性。
|
6月前
|
Java 数据库连接 Maven
手把手教你如何搭建SSM框架、图书商城系统案例
这篇文章是关于如何搭建SSM框架以及实现一个图书商城系统的详细教程,包括了项目的配置文件整合、依赖管理、项目结构和运行效果展示,并提供了GitHub源码链接。
手把手教你如何搭建SSM框架、图书商城系统案例
|
5月前
|
Java 应用服务中间件 数据库连接
ssm项目整合,简单的用户管理系统
文章介绍了一个使用SSM框架(Spring、SpringMVC、MyBatis)构建的简单用户管理系统的整合过程,包括项目搭建、数据库配置、各层代码实现以及视图展示。
ssm项目整合,简单的用户管理系统
|
8月前
|
前端开发 JavaScript Java
计算机Java项目|SSM智能仓储系统
计算机Java项目|SSM智能仓储系统
|
5月前
|
XML Java 数据库连接
如何搭建SSM框架、图书商城系统
这是一份详尽的《Spring + SpringMVC + Mybatis 整合指南》,作者耗时良久整理出约五万字的内容,现已经全部笔记公开。此文档详细地介绍了如何搭建与整合SSM框架,具体步骤包括创建Maven项目、添加web骨架、配置pom文件以及整合Spring、SpringMVC和Mybatis等。无论是对初学者还是有一定基础的开发者来说,都是很好的学习资源。此外,作者还提供了项目源码的GitHub链接,方便读者实践。虽然当前主流推荐学习SpringBoot,但了解SSM框架仍然是不可或缺的基础。
93 0

热门文章

最新文章

  • 1
    前端起dev从110秒减少到7秒, 开发体验大幅提升
    17
  • 2
    无前端经验如何快速搭建游戏站:使用 windsurf 从零到上线的详细指南
    33
  • 3
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
    39
  • 4
    VSCode AI提效工具,通义灵码前端开发体验
    95
  • 5
    开箱即用的GO后台管理系统 Kratos Admin - 前端权限
    13
  • 6
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    47
  • 7
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    84
  • 8
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    36
  • 9
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    159
  • 10
    详解智能编码在前端研发的创新应用
    122