第18章 运用Struts+Hibernate开发物资管理系统
Hibernate作为一个成熟且功能强大的持久层框架,它对JDBC进行了轻量级的对象封装,使程序员可能随心所欲地使用面向对象编程思想来操纵数据库。Struts作为一款优秀的基于MVC的Java Web框架,已经得到了广大企业和Java Web程序员的认可。Struts+Hibernate可谓开发Web程序的黄金组合。
本章将介绍运用Struts+Hibernate开发物资管理系统的全过程。本系统具有以下亮点。
● 通过Struts框架实现MVC模式,不但可以提高网站的开发速度,而且可以增强程序的可读性和易维护性。
● 系统中采用了Struts的RequestProcessor类解决中文乱码问题,使原本繁琐的工作变得非常简单。
● 通过Hibernate的HQL查询及关联操作使数据检索操作变得简单易行。
服务器端:
● 操作系统:Windows 2000 Server
● Web服务器:Tomcat 5.5
● 开发工具包:JDK Version 1.5以上
● 数据库:SQL Server 2000
● 浏览器:IE 6.0
● 分辨率:最佳效果1024×768像素
客户端:
● 浏览器:IE 6.0及以上版本,推荐使用IE 6.0
● 分辨率:最佳效果1024×768像素
18.1 需 求 分 析
物资管理是企业管理非常重要的一环,它对企业的发展起着非常举足轻重的作用。由于物资的种类繁多,在各部门进出频繁,使得物资管理变得十分复杂。开发一套完善的物资管理系统不但可以使物资的管理者能够对物资的整个流程状态、库存状况了如指掌,并为决策管理提供科学依据,从而提高了管理水平和工作效率,而且可以使工作人员甩掉手工记账方式,从而最大限度地减少了手工操作带来的失误,达到事半功倍的效果。物资管理系统作为企业管理自动化、规范化的一部分,对提高企业管理效率、提高企业经济效益发挥不可替代的作用。
18.2 系 统 设 计
18.2.1 项目规划
物资管理系统是一个典型的数据库应用程序,由物资入库、物资出库、物资处理、查询统计、基础信息、系统管理、修改密码等模块组成,其各功能模块如下。
● 物资入库
物资入库主要实现创建采购单、审核入库、借出归还等功能。
● 物资出库
物资出库主要实现部门领用、物资借出、借出审核等功能。
● 物资处理
物资处理主要实现库存盘点、部门报损等功能。
● 查询统计
查询统计主要实现采购单查询、入库查询、部门领用查询、部门领用汇总、部门报损查询、部门报损汇总、借出查询、部门汇总等功能。
● 基础信息
基础信息主要实现供应商信息管理、物资信息管理、部门信息管理等功能。
● 系统管理
系统管理主要实现用户管理、系统初使化等功能。
● 修改密码
修改密码主要用于修改登录用户的密码。
18.2.2 系统功能结构
物资管理系统功能结构如图18.1所示。
18.2.3 业务流程
物资管理系统的业务流程如图18.2所示。
图18.1 系统功能结构图
图18.2 业务流程图
18.3 数据库设计
本系统采用的SQL Server 2000数据库,数据库名为db_Material,共包含12张数据表和一张视图。下面分别给出各数据表、视图的简要说明,数据表之间的关系及主要数据表的结构。
18.3.1 数据表、视图的简要说明
数据表、视图树型结构如图18.3所示,该数据表树型结构图包含本系统中使用的所有用户数据表。
图18.3 数据表及视图树型结构图
18.3.2 数据表关系概要说明
物资管理系统的数据表关系如图18.4所示。
图18.4 数据表关系图
18.3.3 主要数据表的结构
● tb_goods(物资信息表)
物资信息表主要用于保存物资基本信息。表tb_goods的结构如表18.1所示。
表18.1 tb_goods表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
是
|
Hibernate自动编号
|
name
|
varchar
|
50
|
否
|
物资名称
|
spec
|
varchar
|
50
|
否
|
规格
|
unit
|
varchar
|
6
|
否
|
单位
|
price
|
float
|
8
|
否
|
单价
|
producer
|
varchar
|
50
|
否
|
生产厂家
|
ifdel
|
bit
|
1
|
否
|
是否删除
|
● tb_branch(部门信息表)
部门信息表主要用于保存部门信息。表tb_branch的结构如表18.2所示。
表18.2 tb_branch表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
Id
|
int
|
4
|
是
|
Hibernate自动编号
|
Name
|
varchar
|
30
|
否
|
部门名称
|
Tel
|
varchar
|
20
|
否
|
部门电话
|
Memo
|
varchar
|
100
|
否
|
备注
|
● tb_stock_main(采购单主表)
采购单主表主要用于保存采购单概要信息。表tb_stock_main的结构如表18.3所示。
表18.3 tb_stock_main表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
sno
|
varchar
|
17
|
否
|
采购单号
|
principal
|
varchar
|
30
|
否
|
负责人
|
providerid
|
int
|
4
|
否
|
供应商ID
|
username
|
varchar
|
30
|
否
|
操作员
|
createTime
|
smalldatetime
|
4
|
否
|
开单日期
|
state
|
int
|
4
|
否
|
状态(0表示未审核;1表示审核合格;2表示审核不合格)
|
● tb_stock_detail(采购单明细表)
采购单明细表主要用于保存采购单的明细信息。表tb_stock_detail的结构如表18.4所示。
表18.4 tb_stock_detail表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
stockid
|
int
|
4
|
否
|
采购单号
|
goodsid
|
int
|
4
|
否
|
物资ID
|
price
|
money
|
8
|
否
|
单价
|
number
|
int
|
4
|
否
|
数量
|
● tb_storage(库存表)
库存表主要用于保存物资的库存信息。表tb_storage的结构如表18.5所示。
表18.5 tb_storage表
字 段 名 称
|
数 据 类 型
|
字段大小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
goodsid
|
int
|
4
|
否
|
物资ID
|
number
|
bigint
|
8
|
否
|
库存数量
|
● tb_instorage(入库表)
入库表主要用于保存物资的入库信息。表tb_instorage的结构如表18.6所示。
表18.6 tb_instorage表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
ino
|
varchar
|
17
|
否
|
入库单号
|
stockid
|
int
|
4
|
否
|
采购单号
|
createtime
|
smalldatetime
|
4
|
否
|
入库日期
|
username
|
varchar
|
30
|
否
|
操作员
|
● tb_getUse(部门领用信息表)
部门领用信息表主要用于保存部门领用信息。表tb_getUse的结构如表18.7所示。
表18.7 tb_getUse表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
gno
|
varchar
|
17
|
否
|
领用ID
|
goodsid
|
int
|
4
|
否
|
物资ID
|
number
|
int
|
4
|
否
|
领用数量
|
principal
|
varchar
|
20
|
否
|
负责人
|
username
|
varchar
|
30
|
否
|
操作员
|
branchid
|
int
|
4
|
否
|
部门ID
|
createtime
|
smalldatetime
|
4
|
否
|
领用时间
|
● tb_loan(物资借出信息表)
物资借出信息表主要用于保存物资借出信息。表tb_loan的结构如表18.8所示。
表18.8 tb_loan表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
lno
|
varchar
|
17
|
否
|
借出编号
|
goodsid
|
int
|
4
|
否
|
物资ID
|
number
|
int
|
4
|
否
|
借出数量
|
username
|
varchar
|
30
|
否
|
操作员
|
principal
|
varchar
|
30
|
否
|
负责人
|
borrowperson
|
varchar
|
20
|
否
|
借用人
|
btel
|
varchar
|
20
|
否
|
借用人电话
|
bunit
|
varchar
|
30
|
否
|
借用人单位
|
createtime
|
smalldatetime
|
4
|
否
|
借出时间
|
state
|
smallint
|
2
|
否
|
状态
|
taster
|
varchar
|
20
|
否
|
审核人
|
approvetime
|
smalldatetime
|
4
|
否
|
审核时间
|
backperson
|
varchar
|
20
|
否
|
归还人
|
backtime
|
smalldatetime
|
4
|
否
|
归还时间
|
● tb_damage(部门报损信息表)
部门报损信息表主要用于保存部门报损信息。表tb_loan的结构如表18.9所示。
表18.9 tb_loan表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
是
|
Hibernate自动编号
|
branchid
|
int
|
4
|
否
|
部门ID
|
goodsid
|
int
|
4
|
否
|
物资ID
|
续表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
damagenum
|
Int
|
4
|
否
|
报损数量
|
createtime
|
smalldatetime
|
4
|
否
|
报损时间
|
principal
|
varchar
|
20
|
否
|
负责人
|
username
|
varchar
|
30
|
否
|
操作员
|
cause
|
varchar
|
100
|
否
|
报损原因
|
● tb_user(用户信息表)
用户信息表主要用于保存用户及其权限信息。表tb_user的结构如表18.10所示。
表18.10 tb_user表
字 段 名 称
|
数 据 类 型
|
字 段 大 小
|
是 否 主 键
|
说 明
|
id
|
int
|
4
|
否
|
Hibernate自动编号
|
name
|
varchar
|
30
|
否
|
用户名
|
pwd
|
varchar
|
30
|
否
|
密码
|
setInstorage
|
bit
|
1
|
否
|
物资入库
|
setOutstorage
|
bit
|
1
|
否
|
物资出库
|
setDeal
|
bit
|
1
|
否
|
物资处理
|
setQuery
|
bit
|
1
|
否
|
查询统计
|
setBasic
|
bit
|
1
|
否
|
基础信息
|
setSys
|
Bit
|
1
|
否
|
系统管理
|
18.4 网站总体设计
18.4.1 文件夹架构设计
在编写代码之前,可以把系统中可能用到的文件夹先创建出来(例如:创建一个名为image的文件夹,用于保存网站中所使用的图片),这样不但可以方便以后的开发工作,也可以规范网站的整体架构。笔者在开发物资管理系统时,设计了如图18.5所示的文件夹架构图。在开发时,只需要将所创建的文件保存在相应的文件夹中就可以了。
图18.5 文件夹架构图
18.4.2 类的分布架构设计
为了方便读者阅读和有效利用本书附赠光盘中的实例,下面给出系统中使用的类和.xml文件的描述信息,如图18.6所示。
图18.6 类的分布架构图
18.4.3 文件架构
物资管理系统的文件架构如图18.7所示。
图18.7 物资管理系统文件架构
18.4.4 网站首页架构
用户通过“用户登录”模块即可登录到物资管理系统的主界面。系统主界面主要用于根据登录用户的权限,显示该用户可操作的功能菜单。系统主界面的运行结果如图18.8所示。
图18.8 系统主界面的运行结果
为了方便读者阅读和有效利用本书附赠光盘中的实例,笔者将系统主界面的各部分说明以列表形式给出,如表18.11所示。
表18.11 系统主界面说明
区 域
|
名 称
|
说 明
|
对 应 文 件
|
1
|
系统导航
|
主要展示系统菜单、当前系统日期及当前登录用户,同时该页面还具有防止非法用户登录系统的功能
|
top.jsp
|
2
|
业务操作区
|
为业务操作提供显示平台
|
main.jsp
|
3
|
版权信息
|
显示系统的版权信息
|
copyright.jsp
|
18.5 配置Struts
Struts框架需要通过一个专门的配置文件来控制,它就是struts-config.xml,当然也可以取其他名字。网站在“WEB-INF\web.xml”文件中配置一下就可以找到这个Struts配置文件,具体代码如下。
例程18-1:光盘\mr\18\MaterialManage\defaultroot\WEB-INF\web.xml
<display-name>defaultroot</display-name>
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<!—此处省略了配置HTML标签路径的代码-->
</jsp-config>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>debugjsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>
在web.xml中配置Struts的配置文件,实际就是一个Servlet的配置过程,在配置Servlet的config参数中定义Struts的配置文件(包括相对路径),及在Servlet的URL访问里使用的后缀名,本实例中使用“.do”作为后缀名。
接下来的工作就是配置struts-config.xml文件。本实例中的struts-config.xml文件的关键代码如下。
例程18-2:光盘\mr\18\MaterialManage\defaultroot\WEB-INF\struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="goodsForm" type="com.actionForm.GoodsForm" />
…… //此处省略了其他<form-bean>代码
</form-beans>
<action-mappings>
<action name="goodsForm" path="/goods" scope="request" type="com.action.Goods" validate="true">
<forward name="error" path="/error.jsp" />
<forward name="goodsQuery" path="/goodsList.jsp" />
<forward name="goodsaddok" path="/goods_ok.jsp?para=1" />
<forward name="goodsModiQuery" path="/goodsModify.jsp" />
<forward name="goodsmodifyok" path="/goods_ok.jsp?para=2" />
<forward name="goodsdelok" path="/goods_ok.jsp?para=3" />
</action>
…… //此处省略了其他<action></action>代码
</action-mappings>
<controller processorClass="com.action.SelfRequestProcessor" />
<message-resources parameter="ApplicationResources" />
</struts-config>
注意:在使用JBuilder开发应用Struts框架的程序时,web.xml和struts-config.xml文件的配置都将由JBuilder完成。
18.6 配置Hibernate配置文件
创建物资管理系统的Hibernate配置文件hibernate.cfg.xml,该文件中存放着数据库连接驱动程序类、登录数据库的用户名/密码、映射持久化类配置文件的位置等,Hibernate初始化时会自动在classes路径中寻找这个文件,并读取其中的配置信息,为后期数据库操作做准备,其完整代码如下。
例程18-3:光盘\mr\18\MaterialManage\defaultroot\WEB-INF\classes\hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class"><!--指定连接数据库用的驱动-->
com.microsoft.jdbc.sqlserver.SQLServerDriver
</property>
<property name="connection.url"><!--指定连接数据库的路径-->
jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_Material
</property>
<property name="connection.username">sa</property><!--指定连接数据库的用户名-->
<property name="connection.password"></property><!--指定连接数据库的密码-->
<property name="show_sql">true</property><!--当show_sql属性为true时表示在程序运行时在控制台输出SQL语句,默认为false,建议在调试程序时设为true,发布程序之前再改为false,因为输出SQL语句会影响程序的运行速度-->
<mapping resource="com/actionForm/GoodsForm.hbm.xml"/><!--指定持久化类映射文件-->
…… <!--此处省略了指定其他持久化类映射文件的代码-->
</session-factory>
</hibernate-configuration>
注意:在运行光盘中提供的实例程序时,如果登录用户不是sa和空密码,可以根据实际情况修改该文件。
18.7 公共类的编写
在开发过程中,经常会用到一些公共类,如Session管理类及获取日期和时间的类,因此在开发系统前首先应该编写这些工具类。下面将具体介绍物资管理系统中所需要的公共类的编写过程。
18.7.1 Session管理类的编写
Session管理类主要包括获得SessionFactory的代码和打开Session、关闭Session的方法。下面将详细介绍如何编写物资管理系统的Session管理类MySession。
(1)定义MySession类,将其保存到com.core包中,并编写获得SessionFactory的代码,同时导入所需的类包,代码如下。
例程18-4:光盘\mr\18\MaterialManage\src\com\core\MySession.java
package com.core;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
public class MySession {
static SessionFactory sessionFactory;
static {
try {
Configuration config = new Configuration().configure();
sessionFactory = config.buildSessionFactory();
} catch (Exception e) {
System.out.println("创建SessionFactory时的错误信息:" + e.getMessage());
}
}
…… 此处省略的代码将在步骤(2)-(3)中给出
}
(2)编写打开Session的方法openSession,openSession方法的代码如下。
例程18-5:光盘\mr\18\MaterialManage\src\com\core\MySession.java
public static Session openSession() {
Session session = sessionFactory.openSession();
return session;
}
(3)编写关闭Session的方法getDateTime,getDateTime方法的代码如下。
例程18-6:光盘\mr\18\MaterialManage\src\com\core\MySession.java
public static void closeSession(Session session) {
if (session != null) {
session.close();
}
}
18.7.2 获取日期和时间类的编写
获取日期和时间的类主要包括获取系统日期、获取系统日期和时间、格式化日期时间的方法。下面将详细介绍如何编写获取日期和时间的类GetTime。
(1)定义GetTime类,将其保存到com.core包中,并导入所需的类包,代码如下。
例程18-7:光盘\mr\18\MaterialManage\src\com\core\GetTime.java
package com.core;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class GetTime {
…… 此处省略的代码将在步骤(2)-(4)中给出
}
(2)编写获取系统日期的方法getDate,getDate方法的代码如下。
例程18-8:光盘\mr\18\MaterialManage\src\com\core\GetTime.java
public Date getDate(){
Date dateU = new Date();
java.sql.Date date = new java.sql.Date(dateU.getTime());
System.out.println(date);
return date;
}
(3)编写获取系统日期和时间的方法getDateTime,getDateTime方法的代码如下。
例程18-9:光盘\mr\18\MaterialManage\src\com\core\GetTime.java
public String getDateTime(){
SimpleDateFormat format;
Date date=null;
Calendar myDate=Calendar.getInstance();
myDate.setTime(new java.util.Date());
date=myDate.getTime();
format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String rtnStr=format.format(date);
return rtnStr;
}
(4)编写格式化日期时间为“年-月-日 时:分:秒”格式的方法formatTime,formatTime方法的代码如下。
例程18-10:光盘\mr\18\MaterialManage\src\com\core\GetTime.java
public String formatTime(Date date){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str=format.format(date);
return str;
}