how2j.cn

相关下载
文件名 文件大小
tmall_ssm.rar 1m
使用站长秘制下载工具
步骤 1 : 先运行,看到效果,再学习   
步骤 2 : 模仿和排错   
步骤 3 : 页面截图   
步骤 4 : Property   
步骤 5 : PropertyService   
步骤 6 : PropertyServiceImpl   
步骤 7 : PropertyController   
步骤 8 : listProperty.jsp+editProperty.jsp   
步骤 9 : 查询功能讲解   
步骤 10 : 增加功能讲解   
步骤 11 : 编辑功能讲解   
步骤 12 : 修改功能讲解   
步骤 13 : 删除功能讲解   
步骤 14 : 其他-面包屑导航   
步骤 15 : 其他-分页   
步骤 16 : 自己做一遍   

步骤 1 :

先运行,看到效果,再学习

老规矩,先下载右上角的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
步骤 2 :

模仿和排错

在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程
步骤 3 :

页面截图

重启tomcat,通过访问地址

http://127.0.0.1:8080/tmall_ssm/admin_property_list?cid=12

可以看到属性管理的界面

注: 这cid=12是分类的id,根据你的实际运行情况,采取不同的id值
页面截图
步骤 4 :

Property

Property实体类已经和其他所有的实体类一起,在所有逆向工程 这个环节就一起自动生成好了。 不过仅仅有自动生成的实体类代码,还不足以支撑业务需要,所以在Property基础上增加了一个Category 字段。 这个属性的用途将会在编辑功能讲解 步骤里进行讲解。
package com.how2java.tmall.pojo; public class Property { private Integer id; private Integer cid; private String name; /*非数据库字段*/ private Category category; public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } }
步骤 5 :

PropertyService

新建PropertyService,提供CRUD一套。 需要注意的是,因为在业务上需要查询某个分类下的属性,所以list方法会带上对应分类的id。
package com.how2java.tmall.service; import com.how2java.tmall.pojo.Property; import java.util.List; public interface PropertyService { void add(Property c); void delete(int id); void update(Property c); Property get(int id); List list(int cid); }
package com.how2java.tmall.service;
 
import com.how2java.tmall.pojo.Property;

import java.util.List;

public interface PropertyService {
    void add(Property c);
    void delete(int id);
    void update(Property c);
    Property get(int id);
    List list(int cid);
}
步骤 6 :

PropertyServiceImpl

新增PropertyServiceImpl实现PropertyService对应的方法。通过调用自动生成的PropertyMapper就可以实现大部分方法了。
值得注意的是查询的时候用到了辅助查询类:PropertyExample
它的使用也很方便,这一行表示查询cid字段

example.createCriteria().andCidEqualTo(cid);
package com.how2java.tmall.service.impl; import com.how2java.tmall.mapper.PropertyMapper; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.pojo.Product; import com.how2java.tmall.pojo.Property; import com.how2java.tmall.pojo.PropertyExample; import com.how2java.tmall.service.CategoryService; import com.how2java.tmall.service.PropertyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class PropertyServiceImpl implements PropertyService { @Autowired PropertyMapper propertyMapper; @Override public void add(Property p) { propertyMapper.insert(p); } @Override public void delete(int id) { propertyMapper.deleteByPrimaryKey(id); } @Override public void update(Property p) { propertyMapper.updateByPrimaryKeySelective(p); } @Override public Property get(int id) { return propertyMapper.selectByPrimaryKey(id); } @Override public List list(int cid) { PropertyExample example =new PropertyExample(); example.createCriteria().andCidEqualTo(cid); example.setOrderByClause("id desc"); return propertyMapper.selectByExample(example); } }
步骤 7 :

PropertyController

然后就是控制器类,用于映射不同路径的访问。 这个类每个方法的详解将在后续步骤一一展开。
package com.how2java.tmall.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.how2java.tmall.pojo.Category; import com.how2java.tmall.pojo.Property; import com.how2java.tmall.service.CategoryService; import com.how2java.tmall.service.PropertyService; import com.how2java.tmall.util.Page; @Controller @RequestMapping("") public class PropertyController { @Autowired CategoryService categoryService; @Autowired PropertyService propertyService; @RequestMapping("admin_property_add") public String add(Model model, Property p) { propertyService.add(p); return "redirect:admin_property_list?cid="+p.getCid(); } @RequestMapping("admin_property_delete") public String delete(int id) { Property p = propertyService.get(id); propertyService.delete(id); return "redirect:admin_property_list?cid="+p.getCid(); } @RequestMapping("admin_property_edit") public String edit(Model model, int id) { Property p = propertyService.get(id); Category c = categoryService.get(p.getCid()); p.setCategory(c); model.addAttribute("p", p); return "admin/editProperty"; } @RequestMapping("admin_property_update") public String update(Property p) { propertyService.update(p); return "redirect:admin_property_list?cid="+p.getCid(); } @RequestMapping("admin_property_list") public String list(int cid, Model model, Page page) { Category c = categoryService.get(cid); PageHelper.offsetPage(page.getStart(),page.getCount()); List<Property> ps = propertyService.list(cid); int total = (int) new PageInfo<>(ps).getTotal(); page.setTotal(total); page.setParam("&cid="+c.getId()); model.addAttribute("ps", ps); model.addAttribute("c", c); model.addAttribute("page", page); return "admin/listProperty"; } }
步骤 8 :

listProperty.jsp+editProperty.jsp

然后是查询和编辑的jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@include file="../include/admin/adminHeader.jsp"%> <%@include file="../include/admin/adminNavigator.jsp"%> <script> $(function() { $("#addForm").submit(function() { if (checkEmpty("name", "属性名称")) return true; return false; }); }); </script> <title>属性管理</title> <div class="workingArea"> <ol class="breadcrumb"> <li><a href="admin_category_list">所有分类</a></li> <li><a href="admin_property_list?cid=${c.id}">${c.name}</a></li> <li class="active">属性管理</li> </ol> <div class="listDataTableDiv"> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr class="success"> <th>ID</th> <th>属性名称</th> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> <c:forEach items="${ps}" var="p"> <tr> <td>${p.id}</td> <td>${p.name}</td> <td><a href="admin_property_edit?id=${p.id}"><span class="glyphicon glyphicon-edit"></span></a></td> <td><a deleteLink="true" href="admin_property_delete?id=${p.id}"><span class=" glyphicon glyphicon-trash"></span></a></td> </tr> </c:forEach> </tbody> </table> </div> <div class="pageDiv"> <%@include file="../include/admin/adminPage.jsp"%> </div> <div class="panel panel-warning addDiv"> <div class="panel-heading">新增属性</div> <div class="panel-body"> <form method="post" id="addForm" action="admin_property_add"> <table class="addTable"> <tr> <td>属性名称</td> <td><input id="name" name="name" type="text" class="form-control"></td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <input type="hidden" name="cid" value="${c.id}"> <button type="submit" class="btn btn-success">提 交</button> </td> </tr> </table> </form> </div> </div> </div> <%@include file="../include/admin/adminFooter.jsp"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@include file="../include/admin/adminHeader.jsp"%> <%@include file="../include/admin/adminNavigator.jsp"%> <title>编辑属性</title> <div class="workingArea"> <ol class="breadcrumb"> <li><a href="admin_category_list">所有分类</a></li> <li><a href="admin_property_list?cid=${p.category.id}">${p.category.name}</a></li> <li class="active">编辑属性</li> </ol> <div class="panel panel-warning editDiv"> <div class="panel-heading">编辑属性</div> <div class="panel-body"> <form method="post" id="editForm" action="admin_property_update"> <table class="editTable"> <tr> <td>属性名称</td> <td><input id="name" name="name" value="${p.name}" type="text" class="form-control"></td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <input type="hidden" name="id" value="${p.id}"> <input type="hidden" name="cid" value="${p.category.id}"> <button type="submit" class="btn btn-success">提 交</button></td> </tr> </table> </form> </div> </div> </div>
步骤 9 :

查询功能讲解

查询地址admin_property_list映射的是PropertyController的list()方法
1. 获取分类 cid,和分页对象page
2. 通过PageHelper设置分页参数
3. 基于cid,获取当前分类下的属性集合
4. 通过PageInfo获取属性总数
5. 把总数设置给分页page对象
6. 拼接字符串"&cid="+c.getId(),设置给page对象的Param值。 因为属性分页都是基于当前分类下的分页,所以分页的时候需要传递这个cid
7. 把属性集合设置到 request的 "ps" 属性上
8. 把分类对象设置到 request的 "c" 属性上。 ( 这个c有什么用呢? 在后面步骤的 其他-面包屑导航 中会用于显示分类名称)
9. 把分页对象设置到 request的 "page" 对象上
10. 服务端跳转到admin/listProperty.jsp页面
11. 在listProperty.jsp页面上使用c:forEach 遍历ps集合,并显示
查询功能讲解
@RequestMapping("admin_property_list") public String list(int cid, Model model, Page page) { Category c = categoryService.get(cid); PageHelper.offsetPage(page.getStart(),page.getCount()); List<Property> ps = propertyService.list(cid); int total = (int) new PageInfo<>(ps).getTotal(); page.setTotal(total); page.setParam("&cid="+c.getId()); model.addAttribute("ps", ps); model.addAttribute("c", c); model.addAttribute("page", page); return "admin/listProperty"; }
<c:forEach items="${ps}" var="p"> <tr> <td>${p.id}</td> <td>${p.name}</td> <td><a href="admin_property_edit?id=${p.id}"><span class="glyphicon glyphicon-edit"></span></a></td> <td><a deleteLink="true" href="admin_property_delete?id=${p.id}"><span class=" glyphicon glyphicon-trash"></span></a></td> </tr> </c:forEach>
步骤 10 :

增加功能讲解

1. 在listProperty.jsp页面提交数据的时候,除了提交属性名称,还会提交cid
2. 在PropertyController通过参数Property 接受注入
3. 通过propertyService保存到数据库
4. 客户端跳转到admin_property_list,并带上参数cid
增加功能讲解
<form method="post" id="addForm" action="admin_property_add"> <table class="addTable"> <tr> <td>属性名称</td> <td><input id="name" name="name" type="text" class="form-control"></td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <input type="hidden" name="cid" value="${c.id}"> <button type="submit" class="btn btn-success">提 交</button> </td> </tr> </table> </form>
@RequestMapping("admin_property_add") public String add(Model model, Property p) { propertyService.add(p); return "redirect:admin_property_list?cid="+p.getCid(); }
步骤 11 :

编辑功能讲解

1. 在PropertyController的edit方法中,根据id获取Property对象
2. 根据properoty对象的cid属性获取Category对象,并把其设置在Property对象的category属性上
3. 把Property对象放在request的 "p" 属性中
4. 服务端跳转到admin/editProperty.jsp
5. 在editProperty.jsp中显示属性名称
6. 在editProperty.jsp中隐式提供id和cid( cid 通过 p.category.id 获取)

<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
编辑功能讲解
@RequestMapping("admin_property_edit") public String edit(Model model, int id) { Property p = propertyService.get(id); Category c = categoryService.get(p.getCid()); p.setCategory(c); model.addAttribute("p", p); return "admin/editProperty"; }
    @RequestMapping("admin_property_edit")
    public String edit(Model model, int id) {
        Property p = propertyService.get(id);
        Category c = categoryService.get(p.getCid());
        p.setCategory(c);
        model.addAttribute("p", p);
        return "admin/editProperty";
    }
<input type="hidden" name="id" value="${p.id}"> <input type="hidden" name="cid" value="${p.category.id}">


						<input type="hidden" name="id" value="${p.id}">
						<input type="hidden" name="cid" value="${p.category.id}">
步骤 12 :

修改功能讲解

1. 在PropertyController的update方法中获取Property对象
2. 借助propertyService更新这个对象到数据库
3. 客户端跳转到admin_property_list,并带上参数cid
修改功能讲解
@RequestMapping("admin_property_update") public String update(Property p) { propertyService.update(p); return "redirect:admin_property_list?cid="+p.getCid(); }
    @RequestMapping("admin_property_update")
    public String update(Property p) {
        propertyService.update(p);
        return "redirect:admin_property_list?cid="+p.getCid();
    }
步骤 13 :

删除功能讲解

1. 在PropertyController的delete方法中获取id
2. 根据id获取Property对象
3. 借助propertyService删除这个对象对应的数据
4. 客户端跳转到admin_property_list,并带上参数cid
删除功能讲解
@RequestMapping("admin_property_delete") public String delete(int id) { Property p = propertyService.get(id); propertyService.delete(id); return "redirect:admin_property_list?cid="+p.getCid(); }
    @RequestMapping("admin_property_delete")
    public String delete(int id) {
        Property p = propertyService.get(id);
        propertyService.delete(id);
        return "redirect:admin_property_list?cid="+p.getCid();
    }
步骤 14 :

其他-面包屑导航

在属性管理页面的页头,有一个面包屑导航
第一个连接跳转到admin_category_list
第二个连接跳转到admin_property_list?cid=

样式用的是Bootstrap面包屑导航
其他-面包屑导航
<ol class="breadcrumb"> <li><a href="admin_category_list">所有分类</a></li> <li><a href="admin_property_list?cid=${c.id}">${c.name}</a></li> <li class="active">属性管理</li> </ol>
	<ol class="breadcrumb">
	  <li><a href="admin_category_list">所有分类</a></li>
	  <li><a href="admin_property_list?cid=${c.id}">${c.name}</a></li>
	  <li class="active">属性管理</li>
	</ol>
步骤 15 :

其他-分页

这里的分页比起分类管理中的分页多了一个参数cid

1. 在PropertyController.list() 方法中,把&cid= 参数设置到在page对象的param属性上

page.setParam("&cid="+c.getId());


2. 在adminPage.jsp页面中通过${page.param}取出这个参数
其他-分页
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <script> $(function(){ $("ul.pagination li.disabled a").click(function(){ return false; }); }); </script> <nav> <ul class="pagination"> <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=0${page.param}" aria-label="Previous" > <span aria-hidden="true">«</span> </a> </li> <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>> <a href="?page.start=${page.start-page.count}${page.param}" aria-label="Previous" > <span aria-hidden="true">‹</span> </a> </li> <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status"> <li <c:if test="${status.index*page.count==page.start}">class="disabled"</c:if>> <a href="?page.start=${status.index*page.count}${page.param}" <c:if test="${status.index*page.count==page.start}">class="current"</c:if> >${status.count}</a> </li> </c:forEach> <li <c:if test="${!page.hasNext}">class="disabled"</c:if>> <a href="?page.start=${page.start+page.count}${page.param}" aria-label="Next"> <span aria-hidden="true">›</span> </a> </li> <li <c:if test="${!page.hasNext}">class="disabled"</c:if>> <a href="?page.start=${page.last}${page.param}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav>
步骤 16 :

自己做一遍

关于属性管理这一块的学习,推荐如下思路:
1. 先下载右上角可运行项目,配置好了跑一遍
2. 根据接着的讲解,把里面的每一块代码的逻辑,思路,设计思想搞明白,不明不白的在对应页面下提问
3. 都理清楚之后,把可运行项目删掉,按照:查询,增加,删除,编辑,修改的顺序自己从头到尾做一遍

只有,能够独立的做出来,才叫做把这些知识点的内容转化为自己的技能


HOW2J公众号,关注后实时获知布最新的教程和优惠活动,谢谢。


关于 实践项目-天猫整站SSM-属性管理 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 620943819
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: http://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图