JavaWeb商品销售系统的设计与实现

前言

今天,博主接了一个小任务,开发一款JavaWeb网上点餐系统,此外要将该系统更改为鞋城销售系统,药品销售系统以及茶叶销售系统。话不多说,开干!
客户要求,使用他提供的一套数据库操作工具类,博主看了一下,封装挺完善,商量好价格后,便开始了工作!限时两天,四套程序,难度也是不低呀。

工具类介绍

首先我们看一下数据库工具类
数据库工具类对数据库的增删改查进行了封装,其中,查询封装为List与Page两种类型

首先是将其封装为 List 链表形式的数据

// 执行返回多条记录的查询操作,结果被封装到List中。
	public List<Map<String, String>> getList(String sql, String[] params) {
		List<Map<String, String>> list = null;
		init();
		try {
			pstmt = con.prepareStatement(sql);
			setParams(params);
			ResultSet rs = pstmt.executeQuery();
			list = getListFromRS(rs);//将数据集信息进行封装
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			close();
		}
		return list;
	}

下面是封装数据集信息,通过相关的方法获取数据表字段的名称并与之对应

// 将结果集中的内容封装到List中
	private List<Map<String, String>> getListFromRS(ResultSet rs) throws SQLException {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		ResultSetMetaData rsmd = rs.getMetaData();
		while (rs.next()) {
			Map<String, String> m = new HashMap<String, String>();
			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
				String colName = rsmd.getColumnLabel(i);
				String s = rs.getString(colName);
				if (s != null) {
					m.put(colName, s);
				}
			}
			list.add(m);
		}
		return list;
	}

如此,数据封装便完成了,而Page的方法实现是在List的基础上添加了其他属性。page工具添加了一个分页查询属性,及在原本的sql语句后面加上了limit **,此外,还需对整个数据表的数据进行查询,从而确定分页的页数,然后将List作为Object保存到Map中,然后再将总页数,当前页数等信息也封装进去,如此,Page的封装便完成了。

// 查询结果分页时,返回分页信息的Map,包括总页数,每页记录数和当前页中的记录。
	public Map<String, Object> getPage(String sql, String[] params, String curPage) {
		Map<String, Object> page = new HashMap<String, Object>();
		String newSql = sql + " limit " + (Long.parseLong(curPage) - 1) * PAGE_REC_NUM + "," + PAGE_REC_NUM;
		List<Map<String, String>> pageList = getList(newSql, params);
		sql = sql.toLowerCase();
		String countSql = "";
		if (sql.indexOf("group") >= 0) {
			countSql = "select count(*) as tempNum from (" + sql + ") as temp";
		} else {
			countSql = "select count(*) as tempNum " + sql.substring(sql.indexOf("from"));
		}
		String count_s = (String) getMap(countSql, params).get("tempNum");
		long count = Long.parseLong(count_s);
		long totalPage = 0;
		if (count % PAGE_REC_NUM == 0)
			totalPage = count / PAGE_REC_NUM;
		else
			totalPage = count / PAGE_REC_NUM + 1;
		page.put("list", pageList);
		page.put("totalPage", totalPage);
		page.put("curpage", curPage);
		page.put("recNum", PAGE_REC_NUM);
		return page;
	}

当然,还要只能查询一条信息的那种,及我们只获取该数据集中的第一条信息即可

// 执行返回至多一条记录的查询操作,结果被封装到Map中。
	public Map<String, String> getMap(String sql, String[] params) {
		Map<String, String> m = null;
		List<Map<String, String>> l = getList(sql, params);
		if (l != null && l.size() != 0) {
			m = (Map<String, String>) (l.get(0));
		}
		return m;
	}

至此,项目中最重要的查询操作的封装便完成了,接下来便是完成对数据库中改增删的操作了。

// 执行更新类(增删改)的SQL语句,SQL语句中含有占位符。
	public int update(String sql, String[] params) {
		int result = 0;
		init();
		try {
			pstmt = con.prepareStatement(sql);
			setParams(params);
			result = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close();
		}
		return result;
	}

此外关于占位符的处理,即需要填充

// 为预编译的SQL语句中的占位符?设置值,值被放在字符串数组params中。
	private void setParams(String[] params) {
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				try {
					pstmt.setString(i + 1, params[i]);
				} catch (SQLException e) {
					e.printStackTrace();
				}

			}

		}
	}

此外,还有对文件上传工具类的封装

public static String uploadSingleFile(Part part, HttpServletRequest request) {
		String path = null;
		String fileName = getFileName(part);
		if (!fileName.equals("")) {
			// 得到上传文件的文件扩展名
			String fileExtName = getFileExtName(part);
			String newFileName = System.currentTimeMillis() + fileExtName;
			// 得到上传文件保存路径的服务器端硬盘物理路径
			String savePath = request.getServletContext().getRealPath("/img");
			File f = new File(savePath);
			if (!f.exists()) {
				f.mkdirs();
			}
			// 文件上传
			try {
				part.write(savePath + File.separator + newFileName);
				path = "img/" + newFileName;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return path;
	}

在开发工程中,由于涉及下单的日期等问题,博主又封装了时间工具

public String getTime(){
		Long timeStamp = System.currentTimeMillis();  //获取当前时间戳
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp)))); 
        return time;
	}

在这里插入图片描述

至此,封装的工具类便介绍完毕了,接下来我们就要用这一套工具类来完成我们的项目

界面展示

四个项目都是商城销售项目,而其工具类相同,故而项目基本一致,不同之处也就是在一些方法,类的命名方面与前端界面上。
下面将这四个项目的界面展示一下
药品销售平台
网上点餐
网上鞋城
茶叶销售网站
后台管理系统
购物车页面

开发步骤详解

下面,便来介绍这个项目的开发步骤
首先,我们需要来确定我们的前端界面,博主在之前总是自己来做界面,然而结果总是差强人意,之后便使用了一些前端框架,博主常用的是Bootstrap,此外,还会直接拿一些前端的界面来直接用,在这四套系统中,鞋城系统的UI则是博主积攒下的,而其他的三个项目则是自己开发的,其实就是应用了相关的组件,如表单,按钮等,总体来看,界面较为简洁。

大家如果需要学习,可以去搜索 BootStrap中文网 学习相关的前端界面开发方法

言归正传,开始我们的开发步骤
JavaWeb的开发一般都是要遵循三层架构或MVC设计模式,按照客户的demo看也比较接近

项目目录截图如图所示

在这里插入图片描述
按照执行步骤,都要先通过发送Servlet请求来去执行相应的Servlet,然后去调用服务层的逻辑代码以获取数据信息并封装返还,将最终的结果渲染返回至界面,从而完成一次请求
在这里插入图片描述
那么我们以查询操作为例来进行讲解一下实现步骤。

举例

以鞋城后台管理系统中的商品列表为例,该查询结果中包含List与一些分页属性。
首先,我们要知道,要想获取数据,就要发送servlet请求
在这里插入图片描述
紧接着,对号入座找到相应的servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");//设置请求与相应的编码格式,防止乱码
		String sname=request.getParameter("sname");//获取鞋子名称参数
		if(sname==""){
			sname="";
		}
		String curpage=request.getParameter("curpage");//获取当前页参数
		Map<String, Object> shoes=shs.getShoesPage(curpage,sname);
		//将返还结果封装返还
		request.setAttribute("shoes", shoes);	//将数据保存在request域中,可以在页面中显示	request.getRequestDispatcher("/admin/shoe_list.jsp").forward(request, response);//响应返还到相应页面
	}

服务层调用实现数据库相关操作

public  Map<String, Object> getShoesPage(String curpage,String sname){
			String sql = "select shoes.id id,shoes.sname sname,shoes.price price ,types.typename typename,shoes.image image from shoes inner join types on types.id=shoes.typeid where shoes.sname like '%"+sname+"%' ";
			return db.getPage(sql, curpage);
	}

至此便将数据获取完毕了,将信息封装在Map中再依次返还,最终到了我们的界面中
使用el表达式将我们的数据从request域中读取出来

<c:forEach items="${requestScope.shoes.list }" var="shoe">
			<tr>
				<td style="width:80px;height:70px"><img src="${basePath}/${shoe.image }" style="width:60px;height:50px"></td>
				<td>${shoe.sname }</td>
				<td>${shoe.price }</td>
				<td>${shoe.typename }</td>
				<td><a href="${basePath}/ShoeGetById?id=${shoe.id }"><button type="button" class="btn btn-success">编辑</button></a>
					<a href="${basePath}/ShoeDelServlet?id=${shoe.id }"><button type="button" class="btn btn-danger">删除</button></a>
					</td>
			</tr>
			</c:forEach>

实现分页判断

<nav aria-label="...">
				<ul class="pager">
					<c:choose>
								 <c:when test="${requestScope.shoes.curpage eq 1  }">
								 <li><a href="#">上一页</a>
								 </li>
								 </c:when>
								 <c:otherwise>
								 <li><a href="${basePath}/ShoeServlet?curpage=${requestScope.shoes.curpage-1 }&&sname=">上一页</a></li>
								 </c:otherwise>
					</c:choose>
					<li><a href="#">第 ${requestScope.shoes.curpage}</a></li>
					<c:choose>
								 <c:when test="${requestScope.shoes.curpage eq requestScope.shoes.totalPage  }">
								 <li><a href="#">下一页</a>
								 </li>
								 </c:when>
								 <c:otherwise>
								 <li><a href="${basePath}/ShoeServlet?curpage=${requestScope.shoes.curpage+1 }&&sname=">下一页</a></li>
								 </c:otherwise>
					</c:choose></ul>
				</nav>

至此,该项目的查询操作便完成了,至于其他方法的实现,也是如法炮制,相信通过完成这样一个项目,我们便可以对JavaWeb技术有了更深的了解。

码字不易,给个赞呗!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2021年6月15日更新

近日,博主在原有系统框架的基础上,衍生出了其他的项目,其中一个为名画宣传网站,其类型与博客系统类似,具体功能如下:
后台功能:
管理员登录注册 名画管理(增删改查) 名画类别管理 用户管理 评论管理
前台功能
用户登陆注册 名画浏览 按类别检索名画 评论

主要实现功能模块截图

首页首页
实现流程
获取名画列表信息,我们根据其性质可以将其分为List与Page形式。其中List即为将所有的名画信息保存在List列表中
详情
在这里插入图片描述
评论列表
在这里插入图片描述

**后台系统名画在这里插入图片描述
评论管理

在这里插入图片描述
名画类别管理
在这里插入图片描述
名画添加
在这里插入图片描述
那么我们来讲解下这个系统的实现步骤
首先我们需要访问Servlet,其功能为一个超链接,我们的Servlet可以获取请求并给返回结果,其中,其支持get与post两种请求方式,对于一般的超链接请求,可以使用get处理,而对于表单提交的信息,则可以使用post方式提交

首先找到我们的查询超链接

** href="${basePath}/ImgUserServlet?aname=" class=“dreamer”>首页**
再对应找到相关的servlet

在这里插入图片描述
然后到了service层

 public  List<Map<String,String>> getArticle(String aname){
			String sql = "select article.id id,article.aname aname,article.times times ,article.info info,types.typename typename,article.image image from article inner join types on types.id=article.typeid where article.aname like '%"+aname+"%' order by id";
			return db.getList(sql);
	}

将结果返回即可,而在jsp页面中则可以用requestScope.对象名.属性名的方式来获取对应字段的信息

 <c:forEach items="${requestScope.typelist }" var="type">
			<a href="${basePath}/ImgGetByType?type=${type.typename}">${type.typename}</a>
			<span></span>
			</c:forEach>
  • 21
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭祥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值