图4-12 订单信息查询界面
4.6 用户管理模块的实现
用户管理功能是针对管理员的一个功能模块,该功能模块主要是针对职员和供应商的。职员信息的变化是必然的,因此要及时的更新。管理员操作的功能有:新增职工、更新职工、新增供应商、更新供应商。 4.6.1 新增职工功能的实现
点击新增职工,系统就会显示新增职工的一个表单,管理员根据表单填写新增职工的相关信息。然后点击提交,数据就会保存到数据库。职工录入界面如图4-13所示。
图4-13 职工录入界面
26
4.6.2 更新职工功能的实现
点击更新职工,系统就会显示全部的职工信息。管理员若要更改某一职工信息,就可点击更新,则该职工信息就会显示在一个表单上,管理员就可更改相关信息,点击提交,信息就保存在数据库中。若要删除某一职工信息,则点击删除即可。更新职工信息界面如图4-14所示。
图 4-14 更新职工信息界面
4.6.3 新增供应商功能的实现
点击新增供应商,系统就会显示新增供应商的一个表单,管理员根据表单填写新增供应商的相关信息。然后点击提交,数据就会保存到数据库。供应商信息录入界面如图4-15所示。
图4-15 供应商信息录入界面
4.6.4 更新供应商功能的实现
点击更新供应商,系统就会显示全部的供应商信息。管理员若要更改某一供应商信息,就可点击更新,则该供应商信息就会显示在一个表单上,管理员就可更改相关信息,点击提交,信息就保存在数据库中。若要删除某一供应商信息,则点击删除即可。供应商信息更新界面如图4-16
27
所示。
图4-16 供应商信息更新界面
4.7 退出系统模块的实现
用户点击退出系统模块,即可实现退出该系统。然后返回到用户登录的界面。
4.8 系统问题解决方案
虽然对系统开发所涉及到的技术有了一定的掌握,但是在开发的过程中遇到了一些设计方面的问题。本节将讨论这些问题的优化以及对这些问题的解决方案。 4.8.1数据访问的优化以及同步问题
1. 数据访问的优化
本系统存在一些用户或者管理员对一些信息的频繁访问,而每次访问这些信息时,系统都要连接数据库并且从数据库中读取数据发送到用户界面。这样频繁的连接数据库和读取数据势必造成数据读取速度过低。鉴于以上原因本系统需要专门定义一个初始化的类Init,这个类在项目启动的时候初始化。它负责从数据库中读取一次数据,当很多用户以后访问数据时,都到该初始化类中读取。这个类就相当于是一个缓存。多个用户访问相同数据的流程如图4-17所示。
界面
用户1
数据库 图4-17 用户访问流程
以管理员访问供应商信息为例,说明怎样实现数据访问的优化,关键代码如下: public void init() throws ServletException {
// 完成供应商信息的加载,把供应商信息存储到app中,app就是tomcat的一个空间 ArrayList
用户2
初始化类
28
//调用业务逻辑方法查询供应商信息
ServletContext app = this.getServletContext(); app.setAttribute(\ //把供应商信息保存到app中
}
2. 同步问题
上面讨论的数据优化给用户对数据的访问带来了便利,但是与此同时它也是有缺陷的。当数据库中的数据发生改变时,初始化类中的数据就要发生改变,不然就会出现数据不一致的问题。因此只要一个数据在多个地方存在,就会出现数据同步问题。数据同步问题的一种解决方法就是在数据库中的数据发生改变的地方对数据进行及时的同步。以供应商信息发生改变为例,关键代码如下:
this.getServletContext().setAttribute(“Supplier”,dbManage.querySupplier(“”)); 当管理员对供应商信息进行更改时,提交后系统就会在控制层调用业务逻辑层的代码把更改后的数据更新到数据库中,紧接着在控制层执行上述代码,即重新在数据库中查找更新后的供应商信息并保存到application中。 4.8.2 乱码问题
在整个系统的开发过程中,乱码问题是最让人头疼的。不管是页面数据与数据库中的数据之间的传递,还是页面数据与Servlet之间的传递都会产生乱码问题。具体的解决方法就是设置一个过滤器,把编码放到过滤器中并且配置过滤器,任何请求都要先经过过滤器,这样就可以解决编码的问题。关键代码如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter) throws IOException, ServletException { request.setCharacterEncoding(\ //设置客户端请求的编码为gbk response.setCharacterEncoding(\ //设置响应信息的编码为gbk // 如果有下一个过滤器则跳转到下一个过滤器,否则跳转到目标页面 filter.doFilter(request, response);
} 4.8.3 分页问题
当管理员要求查询信息时,有时过多的信息无法在一页完全显示,这样就需要采取分页处理的方法。下面以查询商品信息为例,来说明怎样实现数据的分页处理。首先开发人员要设定每页显示的记录数,当管理员输入关键字商品名称时,系统会根据商品名称查找相应记录并统计出总记录数,总记录数除以每页的记录数就可得出总页数。由于在系统中经常会用到关键字、总页数和当前页这三个属性值,因此把他们保存到session中。每次查询的时候系统会根据关键字和当前页这两个属性从数据库中查找属于该页的记录。在本系统中实现分页处理的关键代码如下:
//控制层代码
if (status.equals(\
String sname=request.getSession().getAttribute(\//从session中拿到关键字
int currentPage=Integer.parseInt(request.getParameter(\//更新session中的当前页
29
request.getSession().setAttribute(\//保存当前页到session中
List
//根据关键字和当前页查询数据库中当前页的所有记录并保存到Goods中 }
//业务逻辑层代码
int size = 5; //定义每页显示的记录数
pre = con.prepareStatement(\AND SID NOT IN(SELECT TOP ((?-1)*?) sid FROM Goods WHERE sname LIKE ?)\//查找(currentPage-1)*size个满足条件的记录之后的5个记录 pre.setString(1, \pre.setInt(2, currentPage); pre.setInt(3, size);
pre.setString(4, \
4.8.4 数据库优化问题
数据库的合理设计是系统进行优化的前提工作。正所谓磨刀不误砍柴工,在系统设计阶段的初期多做一些规划和调整,可以给后期的实现节省很多的时间。数据库设计如果太过冗余就会造成异常,这也叫过度的逆规范化;但若过于独立就会带来较多的连接操作,导致多表连接引起的查询开销增加。因此合理的数据库设计是很重要的。下面以管理员查询商品信息为例,来讨论系统数据库设计的调整和优化。
在系统设计的前期对商品信息表定义了以下几个属性:编号、名称、供应商名称、供应商地址、联系人、电话、Email、类别名称、仓库名称、单价、库存量、所在区、排、座位,其中主码是商品编号。该表属性的设置实现了关系模式的逆规范化,这样可以提高信息的查询速度,用空间来换取时间。
然而在系统后期的设计过程中发现由于在物流管理的整个过程中随时都有可能要插入新的仓库位置、商品类别、区域、排、座位,这样就导致了插入异常。因此需要对关系模式进行适当的规范化,关系模式的规范化有利于减少数据冗余,提高磁盘利用率,减少物理和逻辑的I/O次数,消除数据操作带来的异常。但是如果范式分解的过于彻底,就需要对表做较多的连接运算,导致系统资源的大量开销。因此综合各方面因素设计出了合理的关系模式,将上述商品信息表进行以下分解:
商品信息表(商品编号,名称,供应商编号,类别编号、仓库编号、单价、库存量、区号、排号、座位号)
供应商信息表(供应商编号,名称,负责人,电话,地址,Email) 商品类别表(类别编号,类别名称)
商品仓库表(仓库编号,名称,负责人,地址) 所在区表(区编号,区名称) 所在排表(排编号,排名称) 座位表(座位编号,座位名称)
这样就可以实现对一些信息的插入而不导致插入异常,实现了对系统数据库设计的部分优化。
30