servlet+Jsp电子商城案例-“商品”和“商品分类”实体管理,重点容易失误点总结

一、首先,静态页面不需要自己写。找各种素材图片,需要自己做也行,但一定不如前台开发者做的精美。

个人更喜欢 用比较流行的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操作数据库

*/


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值