一、首先,静态页面不需要自己写。找各种素材图片,需要自己做也行,但一定不如前台开发者做的精美。
个人更喜欢 用比较流行的bootstrap框架,做响应式的页面。
二、数据库表设计,这个不难。而且电子商城总共就几张表。但是个别【特殊字段 需要注意:表字段类型 和对应实体类属性类型。】
这里商品product表,和商品分类category表 关系:product依赖category,表里有外建:分类id:cid。
******product 的isHot字段(是否是热门商品),实体类里最好使用Integer类型,而不是int。因为默认值:前者为null,后者为0。
避免出现添加商品时“未选择是否热门”时,如果是int,就默认是0,默认是不热门。而实际没有选择。不符合要求。Integer不会出现这种情况。
******商品添加日期 时间 字段(商品添加日期),使用String类型,排序高效,使用Date类型,功能强大====待确认。
******product外键字段,对应的bean属性的设计。
/**
----------------老师总结:
1、数据库以及 JavaBean 设计
A、根据程序的需要将事物属性字段化
B、设计 JavaBean 原则
首先必须遵循 JavaBean 设计规范========【三个特殊字段】
特殊字段1:
时间 ------ String(排序快) | Date(功能强大)
特殊字段2:
boolean值-- 设计数据库时,一般使用 int 类型 0 代表 false, 1 代表 true;
优化,映射到JavaBean 建议使用 Integer 这个包装类型,因为默认初始化值是 null
特殊字段3:
外键 ------ 方案1:简单实现,和数据库字段名以及数据类型一致
方案2:优化,可以映射成 外键对应的 具体类型
private Category cat;
2、模块实现
A、确认入口
B、分析该模块的执行流程
C、确认出口
3、注意:项目分层引入了 接口
*/
三、代码框架的搭建。===这是有套路的。必须熟练才能得心应手。
/*===这里是标题无关内容。自己总结
代码MVC分层:这个就是套路:
JSP页面(数据源:传递数据给servlet处理; 显示servlet处理后传递到页面的数据:通常用EL表达式取值。)
servlet(处理器:处理页面请求传递的数据;还能根据传来的参数 控制页面跳转。调service)
service(处理业务逻辑:这里没有其他业务逻辑,只是调dao)
dao(操作数据库:CRUD。实体)
*/
======***这里最大的【技巧】就是:
【在还没有创建下一层代码时,直接使用,根据错误提示,再去新建要用到的类,再去新建方法。
这样逻辑清晰。不容易混乱,而且开发速度快。
例如:
我要去创建“修改商品”链接的请求处理servlet时,必然要用到ProductService,调service的updatePro(pro)方法。
这时,这个方法和类 都还没有呢!没关系,直接写。根据错误提示创建即可。
演示:
ProductService ps = new ProductServiceImpl();//===需要习惯 使用接口。“面向抽象非具体”思想,便于以后代码的更改和拓展,降低耦合。
】
===从页面传递参数开始,servlet-service-dao逐步完成一个单独的功能。稳步推进。
三、servlet处理完,就要跳到页面显示数据了。
-----------------又长篇大论的 一番废话。我都嫌弃自己。O(∩_∩)O哈哈~
******这里最大的【经验】就是:
【有时很多功能,第一眼咋一看,一点实现思路都没有。即使做过类似的。有时隔一段时间就会忘。
比如:修改商品界面 回显的下拉列表里的所有商品分类数据:有时第一感觉就是:修改商品页面都是商品Product的数据。
***容易忘记商品分类Category也是个实体。
修改商品界面不仅要查出当前id的商品Product信息,还要查出所有的分类Category的信息(回显页面供“修改商品分类”)。
===而不是:仅仅查出 当前商品的分类 回显。
***为避免 “写一步,想一步,写一半回头改,效率低效” 这种情况,写之前最好先把思路理一下。
***【分析角度:根据需求,页面需要哪些数据?这些数据属于单个实体还是多个实体?如果属于多个实体,是哪几个实体?】
这样大概分析一下,大致思路理清楚后,再写代码就明确很多了,效率才能上来。
******这个CRUD商品和分类 案例,发现一个【规律】:
******【到达另一个页面 基本都需要先经过servlet处理】。
******《因为基本到达新的页面都需要在新的页面显示数据,所以要先经过servlet拿到要显示的数据。》
例如:
进入显示商品列表页面,先经过servlet调findAll(),查询所有商品信息;
进入修改商品页面,先经过servlet调findPro(pid),查询要修改的商品信息,再到页面显示数据;
进入添加商品页面,不需要进过servlet?===第一感觉又骗了我!!!
【添加商品时的商品分类不是自己随便写的。是从下拉框里选的。所以添加页面需要显示 商品分类 数据。】。所以需要先经过servlet拿到所有商品分类信息。
提交表单后还需要返回商品列表页面,需要更新显示添加的商品,需要经过servlet重新调findAll()。而不是直接返回商品列表页面。
删除商品,不需要进入其他页面。但删除后需要返回商品列表页 动态显示 删除后所有的商品列表。需要经过servlet重新调findAll()。
====这一点和添加,修改表单提交后是一样的。
】
少数页面跳转并不需要经过servlet。
******总之一句话:【页面跳转前】,心里必须有个思考过程:【页面跳转: 目标页面 是否需要我带servlet处理的数据过去?】
四、前面跳转的思路总结完毕。这里记一下:页面显示数据时,特别容易忘的地方。过段时间再看 就会一时间 毫无思路的那种。
/**
容易忘的地方就是: 《修改用户回显数据》时,【复选框 和下拉框 的页面数据显示。】===其实数据显示并不难,和其他表单项的数据显示一样的。
******【真正的容易忘记点:复选框 和下拉框 他俩分别有个checked和selected属性值的显示】。
******需要使用JSTL<c:if>标签 判断:EL页面取到的值是哪一个,符合条件,再添加属性:“checked=‘checked’ ”和“selected='selected' ”。
这里其实和前面学习JS里是一样的。DOM操作表单标签,也是需要注意这两标签的选中属性。
*/
修改商品页面回显的代码:
重点看 复选框:是否热门,判断当前要修改的商品的isHot属性值; 下拉框:默认显示:选中当前要修改的商品的分类。
<body>
<h1>商品修改</h1>
<form action="${pageContext.request.contextPath}/ModifyPro" method="post">
<!-- 修改时要使用 pid -->
<input type="hidden" name="pid" value="${p.pid }" />
<table border="1" width="100%" class="imagetable">
<tr>
<td>商品名称</td>
<td><input type="text" name="pname" value="${p.pname }"/></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="shop_price" value="${p.shop_price }" /></td>
</tr>
<tr>
<td>商品图片【没有上传】</td>
<td><input type="text" name="pimage" value="${p.pimage }" /></td>
</tr>
<tr>
<td>商品是否热门</td>
<td><input type="radio" name="is_hot" value="0" <c:if test="${p.is_hot == 0 }">checked='checked'</c:if> />不热门
<input type="radio" name="is_hot" value="1" <c:if test="${p.is_hot == 1 }">checked='checked'</c:if> />热门
</td>
</tr>
<tr>
<td>商品描述</td>
<td>
<textarea name="pdesc">${p.pdesc}</textarea>
</td>
</tr>
<tr>
<td>商品分类信息</td>
<td>
<!-- <select name="cid">
<option value="1" selected="selected">手机数码</option>
<option value="2">电脑办公</option>
</select> -->
<select name="cid">
<%-- 循环生成 option --%>
<c:forEach var="cat" items="${cList }">
<option value="${cat.cid }" <c:if test="${p.cid == cat.cid }">selected='selected'</c:if> >${cat.cname }</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="修改商品"/>
</td>
</tr>
</table>
</form>
</body>
五、页面显示完毕。页面防止误删,等错误操作。可以给 “删除”链接 添加onclick事件:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/imagetable.css">
<script type="text/javascript">
function toSave(){
//进行页面跳转
location.href = "${pageContext.request.contextPath}/FindCategory";
}
function del(){
var flag = window.confirm("确认删除吗?");
return flag;
}
</script>
</head>
<body>
<table border="1" width="40%" class="imagetable" align="center">
<tr>
<th>商品列表</th>
</tr>
</table>
<hr/>
<table border="1" width="100%" class="imagetable">
<tr>
<th colspan="7" align="right">
<input type="button" value="添加商品" οnclick="toSave()"/>
<input type="button" value="删除商品" οnclick="delPros()"/>
</th>
</tr>
<tr>
<th>商品选中</th>
<th>商品序号</th>
<th>商品名称</th>
<th>商品图片</th>
<th>商品价格</th>
<th>商品描述</th>
<th>商品操作</th>
</tr>
<c:forEach var="pro" items="${pList}" >
<tr>
<td><input type="checkbox" /></td>
<td>${pro.pid }</td>
<td>${pro.pname }</td>
<td><img src="${pro.pimage }" width="100%" /></td>
<td>${pro.shop_price }</td>
<td>${pro.pdesc }</td>
<td width="100px;">
<a href="${pageContext.request.contextPath}/FindProAndCategory?pid=${pro.pid}">修改此商品</a>
<br/>
<a href="${pageContext.request.contextPath}/DelPro?pid=${pro.pid}" οnclick="return del()" >删除此商品</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
----------------------------------------代码:http://pan.baidu.com/s/1gfMmoTl
------------------------------------------完毕。
下面是:整个流程总结。
/**
1、案例需求
实现商品的增删改查操作
2、 案例实现流程 --- 代码编写
A、静态页面没有任何动态效果 --- 项目编写完成一个预期效果
B、搭建项目框架 ------------ 根据项目使用的技术进行导jar包,分层等操作
C、根据静态页面抽取 JavaBean 对象 创建数据库
D、分别实现各个功能模块
商品的增删改查操作
3、页面实现
4、A、导jar包
B、项目分层
service | dao 与 service.impl | dao.impl 的关系:前者存储 接口,后者存储实现类,易于后期出现扩展
接口编程易于程序扩展的 ---- 非接口编程的失败案例:
jdom ---- 为了 API 简洁,使用了类,没有使用接口,后期的扩展性比较差
dm4j ---- dom4j 使用了接口编程,后期扩展更容易
C、编写工具类实现
5、创建数据库以及抽取JavaBean对象
A、二者要进行映射
B、创建时,有个先后顺序:
1、建库,根据库建Bean ------- 传统实现方案
2、建Bean,根据Bean建库 ----- 更符合面向对象的思想
C、分析创建
1、先建库
根据页面上的数据创建表 --- product
根据页面上出现的属性,编写字段 ----- 根据修改或添加(显示的属性较全)页面分析字段
商品表有字段商品类别 ---- 使用多表设计,一对多设计
注意:
表中的字段有的在页面中没有对应的实现
一般情况,表中字段和页面一一对应
页面中实现一般不能多余表中字段
2、创建JavaBean
Date 怎么设置?
方案1:使用 String 对应库中的 date
优点:排序比较方便
缺点:功能弱一些
用于访问量较大的互联网项目
方案2:使用 Date 对象对应库中的 date
优点:功能更强大
缺点:排序速度慢
用于一些互联网内网项目
外键怎么设置?
1、外键使用对象类型--- 更符合面向对象的思想
2、字段名不能和数据库表的字段名一致 ---- 表中是字符串,使用BeanUtils 填充数据时,这个字段也是字符串,
会报类型转换异常
6、模块实现 ---- 查
流程:
1、访问一个Servlet,里面查询所有商品信息
2、携带商品信息跳转到 JSP
3、JSP 取出数据并显示
优化:
问题:正常流程先访问 FindAll 跳转到 jsp,但是也可能直接访问JSP,没有数据
解决:可以将 JSP存储到 web-inf 下面,这个目录下的资源,不能直接访问,必须通过其他资源请求转发到该资源
7、模块实现 ---- 增
流程:
1、按钮添加跳转功能
8、模块实现 ---- 改
流程:
1、单击修改超链接
2、取出要修改的商品信息
3、修改页面,回显要修改的商品的信息、
4、修改完,通过servlet操作数据库
*/