文章目录
Dao层
商铺注册和商铺编辑开发完成之后,我们来做一下商铺列表页面。
- 列表页面需要支持分页 (MySql数据库,我们使用limit关键字)
ShopDao接口
com.imooc.o2o.dao.ShopDao 新增两个接口方法
- selectShopCount
- selectShopList
/**
*
*
* @Title: selectShopList
*
* @Description: 带有分页功能的查询商铺列表 。
*
* 可输入的查询条件:商铺名(要求模糊查询) 区域Id 商铺状态 商铺类别 owner
* (注意在sqlmapper中按照前端入参拼装不同的查询语句)
*
*
* @param shopConditionShop
* @param rowIndex
* 从第几行开始取
* @param pageSize
* 返回多少行数据(页面上的数据量)
*
* 比如 rowIndex为1,pageSize为5 即为 从第一行开始取,取5行数据
*
* @return: List<Shop>
*/
List<Shop> selectShopList(@Param("shopCondition") Shop shopCondition, @Param("rowIndex") int rowIndex, @Param("pageSize") int pageSize);
/**
*
*
* @Title: selectShopCount
*
* @Description: 按照条件查询 符合前台传入的条件的商铺的总数
*
* @param shopCondition
*
* @return: int
*/
int selectShopCount(@Param("shopCondition") Shop shopCondition);
ShopDao.xml配置SQL
/o2o/src/main/resources/mapper/ShopDao.xml
因为统计的SQL和查询商铺列表的SQL中的where条件是相同的,所以这里我们使用SQL片段的方式,简化配置
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的
- 注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:<include refid="namespace.sql片段”/>
<sql id="selectShopByCondition">
<!-- 可输入的查询条件:
商铺名(要求模糊查询)
区域Id
商铺状态
商铺类别
owner
(注意在sqlmapper中按照前端入参拼装不同的查询语句) -->
<!-- 商铺名(要求模糊查询) -->
<if test="shopCondition.shopName != null and '' != shopCondition.shopName">
<!-- 两种写法都可以 注意第二种是 ${}传值 -->
<!--
#{}和${}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,
#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。
如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,
${}可以接收简单类型值或pojo属性值,
如果parameterType传输单个简单类型值,${}括号中只能是value。
-->
<!-- and s.shop_name like concat('%',#{shopCondition.shopName},'%')-->
and s.shop_name like '%${shopCondition.shopName}%'
</if>
<!-- 区域Id -->
<if test="shopCondition.area != null and shopCondition.area.areaId != null ">
and s.area_id = #{shopCondition.area.areaId}
</if>
<!-- 商铺状态 -->
<if test="shopCondition.enableStatus !=null">
and s.enable_status = #{shopCondition.enableStatus}
</if>
<!-- 商铺类别 -->
<if test="shopCondition.shopCategory != null and shopCondition.shopCategory.shopCategoryId != null ">
and s.shop_category_id = #{shopCondition.shopCategory.shopCategoryId}
</if>
<!-- owner -->
<if test="shopCondition.owner != null and shopCondition.owner.userId != null">
and s.owner_id = #{shopCondition.owner.userId}
</if>
</sql>
<select id="selectShopList" resultMap="shopMap">
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>
<include refid="selectShopByCondition"/>
</where>
AND s.area_id = a.area_id
AND s.shop_category_id = sc.shop_category_id
ORDER BY s.priority DESC
LIMIT #{rowIndex} , #{pageSize}
</select>
<select id="selectShopCount" resultType="Integer">
SELECT
count(1)
FROM
tb_shop s,
tb_area a,
tb_shop_category sc
<where>
<include refid="selectShopByCondition"/>
</where>
AND s.area_id = a.area_id
AND s.shop_category_id = sc.shop_category_id
</select>
DAO层单元测试
结合tb_shop中数据,编写如下单元测试
@Test
public void testQueryShopListAndCount() {
Shop shopCondition = new Shop();
PersonInfo owner=new PersonInfo();
owner.setUserId(1L);
shopCondition.setOwner(owner);
List<Shop> shopList = shopDao.queryShopList(shopCondition, 0, 5);
int count = shopDao.queryShopCount(shopCondition);
System.out.println("店铺列表的大小:" + shopList.size());
System.out.println("店铺总数:" + count);
}
Service层
ShopService接口中仅需要定义一个接口方法,在该接口方法的实现类中调用DAO层的两个方法 selectShopList 和 selectShopCount ,并将数据封装到ShopExecution中,以便控制层获取数据,在View层做展示。
ShopExecution 这里增加了一个空构造函数,方便实例化并调用set方法,将shopList和shopCount 封装到ShopExecution 中
ShopService接口新增接口方法
/**
*
*
* @Title: getShopList
*
* @Description: 获取商铺列表. 在这一个方法中同样的会调用查询总数的DAO层方法,封装到ShopExecution中
*
* @param shopCondition
* @param pageIndex
* 前端页面 只有第几页 第几页 定义为pageIndex
* @param pageSize
* 展示的行数
* @throws ShopOperationException
*
* @return: ShopExecution
*/
ShopExecution getShopList(Shop shopCondition, int pageIndex, int pageSize) throws ShopOperationException;;
ShopServie接口实现类
@Override
public ShopExecution getShopList(Shop shopCondition, int pageIndex, int pageSize) throws ShopOperationException {
// 前台页面插入的pageIndex(第几页), 而dao层是使用 rowIndex (第几行) ,所以需要转换一下
int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);
List<Shop> shopList = new ArrayList<Shop>();
ShopExecution se = new ShopExecution();
// 查询带有分页的shopList
shopList = shopDao.selectShopList(shopCondition, rowIndex, pageSize);
// 查询符合条件的shop总数
int count = shopDao.selectShopCount(shopCondition);
// 将shopList和 count设置到se中,返回给控制层
if (shopList != null) {
se.setShopList(shopList);
se.setCount(count);
} else {
se.setState(ShopStateEnum.INNER_ERROR.getState());
}
return se;
}
单元测试
@Test
public void testGetShopList(){
Shop shopCondition=new Shop();
ShopCategory sc=new ShopCategory();
sc.setShopCategoryId(22L);
shopCondition.setShopCategory(sc);
ShopExecution se=shopService.getShopList(shopCondition,2,2);
System.out.println("店铺列表数:"+se.getShopList().size());
System.out.println("列表总数为:"+se.getCount());
}
Controller层
按照页面原型 控制层有2个功能要开发
- 获取商铺列表
- 然后根据连接对某个单一的商铺进行操作(管理页面主要是对session部分的操作)
ShopController
/**
*
*
* @Title: getShopList
*
* @Description: 从session中获取当前person拥有的商铺列表
*
* @param request
* @return
*
* @return: Map<String,Object>
*/
@RequestMapping(value = "/getshoplist", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getShopList(HttpServletRequest request) {
Map<String, Object> modelMap = new HashMap<String, Object>();
// 现在还没有做登录模块,因此session中并没有用户的信息,先模拟一下登录 要改造TODO
PersonInfo personInfo = new PersonInfo();
personInfo.setUserId(1L);
personInfo.setName("小工匠");
request.getSession().setAttribute("user", personInfo);
// 从session中获取user信息
personInfo = (PersonInfo) request.getSession().getAttribute("user");
try {
Shop shopCondition = new Shop();
shopCondition.setOwner(personInfo);
ShopExecution se = shopService.getShopList(shopCondition, 1, 99);
modelMap.put("success", true);
modelMap.put("shopList", se.getShopList());
modelMap.put("user", personInfo);
} catch (ShopOperationException e) {
e.printStackTrace();
modelMap.put("success", false);
modelMap.put("errMsg", e.getMessage());
}
return modelMap;
}
/**
*
*
* @Title: shopManagement
*
* @Description: 从商铺列表页面中,点击“进入”按钮进入
* 某个商铺的管理页面的时候,对session中的数据的校验从而进行页面的跳转,是否跳转到店铺列表页面或者可以直接操作该页面
*
* 访问形式如下
* http://ip:port/o2o/shopadmin/shopmanagement?shopId=xxx
*
* @return
*
* @return: Map<String,Object>
*/
@RequestMapping(value = "/getshopmanageInfo", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> getShopManageInfo(HttpServletRequest request) {
Map<String, Object> modelMap = new HashMap<String, Object>();
// 获取shopId
long shopId = HttPServletRequestUtil.getLong(request, "shopId");
// 如果shopId不合法
if (shopId < 0) {
// 尝试从当前session中获取
Shop currentShop = (Shop) request.getSession().getAttribute("currentShop");
if (currentShop == null) {
// 如果当前session中也没有shop信息,告诉view层 重定向
modelMap.put("redirect", true);
modelMap.put("url", "/o2o/shopadmin/shoplist");
}else{
// 告诉view层 进入该页面
modelMap.put("redirect", false);
modelMap.put("shopId", currentShop.getShopId());
}
} else { // shopId合法的话
Shop shop = new Shop();
shop.setShopId(shopId);
// 将currentShop放到session中
request.getSession().setAttribute("currentShop", shop);
modelMap.put("redirect", false);
}
return modelMap;
}
单元测试
单元测试我们开发完页面后一并测试。