摘要:
本篇博文是“Java 秒杀系统实战系列文章”的第四篇,从这篇文章开始我们将进入该秒杀系统相关业务模块的代码实战!本篇博文将首先从最简单的业务模块入手,即如何实现“获取待秒杀商品的列表以及查看待秒杀的商品详情”功能!
内容:
对于“待秒杀商品列表及其详情的展示”这一功能,我们将采用目前比较流行的 mvc 开发模式来实现!值得一提的是,这一功能模块涉及的主要数据库表为“商品信息表 item”、“待秒杀商品信息 item_kill”。
一、“待秒杀商品列表”代码实战
(1)首先是在 ItemController 控制器中开发“获取待秒杀商品列表”的请求方法,其源代码如下所示:
// 获取商品列表
@RequestMapping(value = {"/","/index",prefix+"/list",prefix+"/index.html"},method = RequestMethod.GET)
public String list(ModelMap modelMap){
try {
// 获取待秒杀商品列表
List<ItemKill> list=itemService.getKillItems();
modelMap.put("list",list);
log.info("获取待秒杀商品列表 - 数据:{}",list);
}catch (Exception e){log.error("获取待秒杀商品列表 - 发生异常:",e.fillInStackTrace());
return "redirect:/base/error";
}
return "list";
}
控制器的这一方法在获取到待秒杀商品的列表信息后,将通过 modelMap 的形式将数据列表返回给到前端的页面 list.jsp 中进行渲染!其中,itemService.getKillItems() 主要用于获取待秒杀商品的列表信息,其源代码如下所示:
@Autowired
private ItemKillMapper itemKillMapper;
// 获取待秒杀商品列表
@Override
public List<ItemKill> getKillItems() throws Exception {return itemKillMapper.selectAll();
}
(2)紧接着是开发 itemKillMapper.selectAll() 方法,其主要是基于 Mybatis 在配置文件中写动态 Sql,该 Sql 的作用在于“获取待秒杀商品的列表”,其源代码如下所示:
<!-- 查询待秒杀的活动商品列表 -->
<select id="selectAll" resultType="com.debug.kill.model.entity.ItemKill">
SELECT
a.*,
b.name AS itemName,
(CASE WHEN (now() BETWEEN a.start_time AND a.end_time AND a.total > 0)
THEN 1
ELSE 0
END
) AS canKill
FROM item_kill AS a LEFT JOIN item AS b ON b.id = a.item_id
WHERE a.is_active = 1
</select>
在这里的 Sql,Debug 是采用了 Left Join 左关联查询的方式获取列表信息,目的是为了获取“商品信息表”中的商品信息,如“商品名称”等等。
值得一提的是,在这里 Debug 还使用了一个小技巧,即采用一个字段 canKill 来表示当前“待秒杀的商品”是否可以被秒杀 / 被抢购!其判断的标准为:
当待秒杀的商品的剩余数量 / 库存,即 total 字段的取值大于 0 时,并且“当前的服务器时间 now() 处于待秒杀商品的抢购开始时间 和 抢购结束时间的范围内”时,canKill 的取值将为 1,即代表可以被抢购或者被秒杀。否则 canKill 的取值将为 0。
(3)至此,“待秒杀商品列表”这一功能模块的后端代码开发已经完成了!前端发起请求后,请求将首先到达 controller,通过请求路径 url 映射到某个方法进行调用,controller 的方法首先会进行最基本的数据校验,然后通过调用 service 提供的接口获取真正的业务数据,最后是在 service 中执行真正的 dao 层层面的数据查询或者数据操作逻辑,最终完成整个业务流的操作。
(4)接下来是开发一个页面 list.jsp 用于展示“待秒杀商品列表的信息”,下面展示了该页面的部分核心源码,如下图所示:
从该代码中可以看出,当 canKill 字段取值为 1 时,将可以点击“详情”进行查看;否则,将会提示相应的信息!即“判断是否可以秒杀”的逻辑 Debug 是将其放在了后端来实现!
(5)至此,“获取待秒杀商品列表”这一功能模块的前后端代码实战已经完毕了,点击运行整个项目,将整个系统运行在外置的 tomcat 服务器中,观察控制台的输出信息,如果没有报错,这说明整个系统的代码在语法级别层面是木有问题的。如下图所示为整个秒杀系统、项目在运行起来之后的首页:
虽然不是很美观,但是 Debug 觉得还是凑合着用吧 哈哈!!
二、“待秒杀商品详情”代码实战
(1)接下来是点击“详情”,查看“待秒杀商品的详情信息”,对于这个功能模块,其实还是比较简单的,其核心主要是根据“主键”进行查询。同样的道理,首先需要在 ItemController 控制器中开发接收前端请求的功能方法,其源代码如下所示:
/**
* 获取待秒杀商品的详情
* @return
*/
@RequestMapping(value = prefix+"/detail/{id}",method = RequestMethod.GET)
public String detail(@PathVariable Integer id,ModelMap modelMap){if (id==null || id<=0){return "redirect:/base/error";}
try {ItemKill detail=itemService.getKillDetail(id);
modelMap.put("detail",detail);
}catch (Exception e){log.error("获取待秒杀商品的详情 - 发生异常:id={}",id,e.fillInStackTrace());
return "redirect:/base/error";
}
return "info";
}
该控制器的方法在获取到待秒杀商品的详情后,将通过 modelMap 把详情信息塞回 info.jsp 前端页面中进行渲染展示!
(2)紧接着是 itemService.getKillDetail(id) 的开发,即用于获取“待秒杀商品的详情”,其源代码如下所示:
/**
* 获取待秒杀商品详情
*/
@Override
public ItemKill getKillDetail(Integer id) throws Exception {ItemKill entity=itemKillMapper.selectById(id);
if (entity==null){throw new Exception("获取秒杀详情 - 待秒杀商品记录不存在");
}
return entity;
}
其中,itemKillMapper.selectById(id); 主要是基于 Mybatis 在配置文件中写动态 Sql,该 Sql 的主要功能为根据主键查询待秒杀商品的详情,其源代码如下所示:
<!-- 获取秒杀详情 -->
<select id="selectById" resultType="com.debug.kill.model.entity.ItemKill">
SELECT
a.*,
b.name AS itemName,
(CASE WHEN (now() BETWEEN a.start_time AND a.end_time AND a.total > 0)
THEN 1
ELSE 0
END
) AS canKill
FROM item_kill AS a LEFT JOIN item AS b ON b.id = a.item_id
WHERE a.is_active = 1 AND a.id= #{id}
</select>
从该 Sql 中不难看出,其实就是在“获取待秒杀商品列表”的 Sql 中加入“主键的精准查询”!
(3)最后是在页面 info.jsp 渲染展示该详情信息,如下图所示为该页面的部分核心源代码:
从该页面的部分核心源代码中可以看出,为了避免有人“跳过页面的请求,直接恶意刷后端接口”,在该页面仍然再次进行了一次判断(在后面执行“抢购 / 秒杀”请求时,后端接口还会再次进行判断的,所有这些都是为了安全考虑!)
(4)至此,关于“待秒杀商品的详情展示”的功能的前后端代码实战已经完成了!再次将整个系统 / 项目运行在外置的 tomcat 服务器中,点击列表页中的“详情”按钮,可以看到待秒杀商品的详情信息,如下图所示:
至此,本文所要分享介绍的内容已经完成了,即主要分享介绍了“获取待秒杀商品的列表”和“查看待秒杀商品的详情”功能!
补充:
1、目前,这一秒杀系统的整体构建与代码实战已经全部完成了,完整的源代码数据库地址可以来这里下载:https://gitee.com/steadyjack/… 记得 Fork 跟 Star 啊!!!
2、实战期间有任何问题都可以留言或者与 Debug 联系、交流;Debug 的微信:debug0868 Debug 的 QQ:1948831260