模仿天猫实战【SSM版】——后台开发
上一篇文章链接:模仿天猫实战【SSM版】——项目起步

后台需求分析
在开始码代码之前,还是需要先清楚自己要做什么事情,后台具体需要实现哪些功能:

- 注意: 订单、用户、订单、推荐链接均不提供增删的功能。
后台界面设计
不像前端那样有原型直接照搬就可以了,后台的设计还真的有难到我...毕竟我是一个对美有一定要求的人,一方面想尽量的简洁、简单,另一方面又不想要太难看,那怎么办呢?

那当然是找模板了,找到一个顺眼的下载下来就开始改,
这个模板的原地址在这里:戳这里

顺便安利一下 FireFox ,真是开发神器,配合着修改,棒棒哒:

经过一番折腾...

摁,就这风格了,而且我还发现右上角的【Search】框是下载的模板用 js 实现的...对于管理来说更加方便了....而且居然还实现了分页....
一个邪恶的想法又诞生了...
一些规定
- 为了降低项目的难度,我们做了很多的精简,现在我们作出如下的规定:
- 全站没有商家,只有一家 Tmall ,后台没有验证,可以直接进入
- 前台的路径就是默认路径,后台的路径需要加上 “/admin” 后缀,如访问后台则为:localhost/admin (默认为分类管理页)
- 管理路径统一为:admin/listXxxxx,如分类管理路径为:admin/listCategory,用户管理路径为:admin/listUser,诸如此类
- 编辑路径统一为:admin/editXxxxx,如编辑分类路径为:admin/editCategory,产品编辑页为:admin/editProduct,诸如此类
- 删除路径统一为:admin/deleteXxxxx
- 更新路径统一为:admin/updateXxxxx
- 关于页面路径的一些规定:
- 前端页面统一在【WEB-INF/views】下,后端页面统一在【WEB-INF/views/admin】下
分类管理
正式开始编写我们的代码,以 Category 为例。
编写 Service 层
我们需要在这一层上考虑需要完成的功能,对应我们上面画的后台功能图,分类管理也就是完成分类的查询还有修改的工作:
- 编写 CategoryServiceImpl :
在同一包下编写实现类
编写 CategoryController
根据业务需求可以很容易的编写出来:
JSP 相关文件编写
自己研究了一会儿这个模板,感觉还是挺好改的,然后就给改成了大概以下这个样子(自己在数据库中加入了 16 条数据):
- 分类管理页

- 分类编辑页

模板下载下来之后文件目录是这样的:

我们直接整个拷贝【assets】文件夹放在【webapp】目录下,然后根据模板里面的代码就可以开始修改了,修改下来的两个文件源码如下:
- listCategory.jsp
- editCategory.jsp
这样就完成了 Category 的后台管理模块
其他模块的思路跟 Category 如出一辙,就比较偏向于体力劳动了...
- 注意: 所有本类的 id 属性均为
id
,所有外键的 id 都是属性名_id
这样的格式,保持统一!
Example 条件查询
MyBatis 逆向工程自动生成文件的时候自动生成了 Example 条件查询类,我们到底应该怎么使用它呢,这里简要的说明一下。
不得不说这个东西还挺神奇,也很方便,比如我们需要查询 category_id 对应下的属性表,我们可以这样写:
通过方法名其实也很容易看懂这些是什么意思,我们首先创建了一个 PropertyExample 实例对象,然后通过 .or()
方法开启条件查询,.andCategory_idEqualTo()
匹配对应的 category_id ,自动生成的 sql 语句就像这样:

IDEA 快速重构
当我编写好了 PropertyService 、PropertyServiceImpl、 PropertyController 之后再想要去编写 Product 的这一系列文件的时候,发现其实很多代码都是重复的,只是很少一部分的代码需要改动,暂时不考虑设计模式的话,我们可以使用 IDEA 来完成快速重构:
- 直接复制 PropertyController 的代码到 ProductController 中,然后【Ctrl + F】搜索 Property :

我们可以发现所有的 Property 都高亮了,然后我们怎么批量修改呢?

然后继续疯狂码代码...
开发过程中遇到的一些问题
PropertyValue 遇到的麻烦

PropertyValue 属性值表,这个表关联了两个外键,一个指向 Product ,另一个指向 Property ,当我按照之前的设计把 listProduct.jsp 设计成下面这个样子的时候,点击【编辑属性】,Property 的信息应该怎么传递?


- 也就是说,如何处理从 listProduct 跳转到 listPropertyValue 页面时凭空跳出来的 Property 的相关信息?
解决方案:
在 PropertyValueServiceImpl 中增加:
我们现在有 category_id 和 product_id ,我们可以利用 Property 和 Category 之间的联系,通过 category_id 查询出所有对应的 Property ,然后再筛选出同时匹配 property_id 和 product_id 的 PropertyValue:
emmm...这样的思路出来之后,对应的 Controller 就清晰了:
加入一条数据测试:

- bingo!
另一个问题是添加属性值:
添加的属性值必须是当前 Category 下有的属性值,所以我们可以在 Controller 上自动注入一个 PropertyService 通过 category_id 查询到当前分类下所有的 Property 然后传递给 listPropertyValue :
期间发现一个 BUG,PropertyValue 表里的 property_id 居然写成了 properti_id,吓得我赶紧检查了一下所有表的字段,其他的没问题,重新生成一下逆向工程
然后获取属性名称:

- 完善之后大概是这样:

产品图片管理
产品图片的管理需要涉及到文件的上传操作,我们需要先提供必要的 jar 包依赖:
- commons-fileupload
- commons-io
同样的搜索 maven 库添加依赖到 pom.xml中:
产品图片如何管理?
- 规定一:
所有的产品图片均保存在【img/product/】对应的 product_id 目录下,并且默认的文件名为 1,2,3,4,5 ,例如 product_id 为 1 的产品的产品图片 1 保存于:【img/product/1/1.jpg】 - 规定二:
每一个产品对应五张图片,文件名分别为 1.jpg ,2.jpg 以此类推,不能少也不能多,删除也只是将对应目录下的图片删除,id 并不改变 - 规定三:
默认产品打开的大图即为该产品图片目录中的 1.jpg
- 界面大概设计成了这样:

- 莫名其妙一个 BUG:
我把表单设计成了这样,隐藏了两个属性,一个 product_id,一个 id:

为了方便操作,我想要直接申明两个参数用来接收上面的两个属性,大概是这样:

但是上面两种方法都不行,我还查了一些资料在 @RequestParam 注解里设置了 required 属性,仍然获取不到,但是我改成用 ProductImage 来接收就好了..Why?

后来写着写着,又必须要使用上面两种方法了....
- 根据我们的规定来完成代码
ProductImageService 层还是跟之前的没有多大的区别,但是值得注意的是,根据我们的规定,我们的删除需要做一些改动(根据 product_id 批量删除):
- 首先在 ProductController 中 add 和 delete 方法中增加以下代码:
然后编写我们的 ProductImageController :
- 再优化一下界面的东西,增加没有图片显示的 error 图片,大概就是这个样子:

这里就只贴一下 table 的代码吧:
在写图片管理的时候又遇到一个坑
在删除顶层数据库数据的时候,要注意删除其下的有外键关联的数据,特别是 product_id 这个东西,是很多表的外键,删除 product 之前需要先清空有关联的其他表的数据....
总之坑是很多啦..不过项目在进展总归是好事...耐心耐心...
接着码代码....
还剩下一些体力活的东西,就先结博文啦...(心累.jpg)
有一些催更的朋友,希望能别催啦...每天都在码啦,而且本身也是很low的东西,写完之后我会上传 github 的。
总结

当我给自己埋了一个大坑说要模仿天猫,并且陷进去的时候,一方面痛苦着一方面也察觉了自己很多不足的地方,就觉得还是很值得,现在来做一下简短的总结。
- 进度比想象中慢了很多,虽然一步一步按照之前的分析图来编写代码总体是顺畅的,但是有那种写着写着突然发现之前的设计有问题的感觉,中途也改了几次,发现自己分析问题不够全面。
- 项目中有许多类似的代码,并且在 Controller 和 Impl 中不断有其他的东西加入,总觉得是糟糕的代码,但是又不知道应该进一步如何改进。
- 方向永远比努力重要,在行动之前思考清楚,我一直觉得是很重要的一点,我觉得通过对项目的分析,对我项目的进展有一个整体的构思,各个模块该有什么功能都比较清晰,特别在编写 JSP 文件的时候能明显感觉不会很迷茫,这是比较好的一点
- 发现自己阅读代码量很少,这种感觉体现在很多地方,一是写代码时感觉到自己思想的局限性,二是觉得自己写的代码有很多的相似性,虽然这个项目是自己突发奇想的想要去做的,但是有很多细节的地方,是自己没有去注意到的,比如类型要求、边界判断、事务处理等等等...
欢迎转载,转载请注明出处!
简书ID:@我没有三颗心脏
github:wmyskxz
欢迎关注公众微信号:wmyskxz_javaweb
分享自己的Java Web学习之路以及各种Java学习资料
__EOF__

本文链接:https://www.cnblogs.com/wmyskxz/p/8969842.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?