小型仓库管理系统的详细设计实现.docx
- 文档编号:26476016
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:27
- 大小:26.13KB
小型仓库管理系统的详细设计实现.docx
《小型仓库管理系统的详细设计实现.docx》由会员分享,可在线阅读,更多相关《小型仓库管理系统的详细设计实现.docx(27页珍藏版)》请在冰豆网上搜索。
小型仓库管理系统的详细设计实现
小型仓库管理系统的详细设计及实现
1.系统设计概述
(1)问题域部分,设计构造一组为底层应用建立模型的类和对象,细化分析结果;由建立数据对象部分实现。
(2)人机交互部分,设计一组有关类接口视图的用户模型的类和对象,设计用户界面;由建立商品数据维护界面部分实现。
(3)任务管理部分,确定系统资源的分配,设计用于系统中类的行为控制的对象/类;由建立商品类别显示模型和商品类型模型部分以及建立商品数据维护界面部分共同实现。
(4)数据管理部分,确定持久对象的存储,将对象转换成数据库记录或表格;由连接数据库和建立商品数据访问对象部分实现。
2.连接数据库
要通过Java访问数据库,必须要使用JDBC(JavaDataBaseConnectivity,java数据库连接),访问不同的数据库,采用的JDBC驱动程序也不同。
连接Access采用Jdbc-odbc桥的方式比较方便,不需要引入额外的驱动程序包。
主流的数据库都提供了专门的JDBC驱动,如ORCALE、SqlServer、Sybase等等,对于微软的Access和Excel以及其他的一些小型的桌面数据库,可以通过JDBC-ODBC桥接的方式来访问。
通过编码,我们不需要在环境中配置ODBC数据源,就可以直接访问这些小型桌面数据库。
在应用系统中,数据库的连接参数一般都是写在配置文件当中,以防止数据库的属性的变化导致程序的修改。
对于本任务来说,Access是桌面数据库,我们需要知道的只是Access数据库文件的路径,因此我们可以将Access数据库文件拷贝到发布路径下,从而可以通过编码获得数据库文件路径,而不需要使用配置文件。
packagetest.sample.dao;
import.URL;
importjava.sql.Connection;
importjava.sql.DriverManager;
publicclassDaoFactory{
staticpublicConnectiongetConnection()throwsException{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加载数据库驱动
URLdbUrl=DaoFactory.class.getClassLoader().getResource("Mystock.mdb");
StringdbPath=dbUrl.getPath();//通过Java的类加载机制,获得数据库文件路径
if(dbPath.charAt(0)=='/'){//去掉路径的第一个字符/
dbPath=dbPath.substring
(1);
}
Stringurl="jdbc:
odbc:
driver={MicrosoftAccessDriver(*.mdb)};DBQ="+dbPath;
Connectioncon=DriverManager.getConnection(url,"sa","");
returncon;
}
}
Class.forName方法的作用是通过类的完整路径名获得一个类的实例,在本例子中的作用是加载我们要使用的数据库驱动。
在使用DriverManager获得数据库连接前,必须通过此语句加载数据库驱动。
ClassLoader类负责管理Java编译后代码的加载,因此能够获取class文件的加载路径,也就是应用的发布路径。
我们把数据库文件放到发布路径下(即class文件所在路径),即可以通过ClassLoader类的getResource方法获得该文件的绝对路径。
由于获得的绝对路径的第一个字符是“/”,这是为了兼容不同的操作系统而导致的,这个符号在Access的数据库路径上是不合法的,需要去掉。
通过数据库url,提供数据库的驱动描述,以及数据库的路径,就可以使用DriverManager类来获得数据库连接。
3.建立商品数据访问对象
从数据库中提取数据,以及向数据库中插入记录和删除数据,都必须使用SQL语句来完成。
因此数据访问对象的方法,实际上就是通过Java数据访问对象,在数据库数据和数据对象之间进行转换。
在数据库的访问中,我们需要用到几个数据访问对象:
1.java.sql.Connection:
用来获得数据库连接。
2.java.sql.PreparedStatement和java.sql.Statement:
都可以用来执行SQL语句。
其中PreparedStatement的功能较强,SQL语句被预编译并且存储在PreparedStatement对象中。
然后可以使用此对象高效地多次执行该语句。
PreparedStatement可以设置set方法设置参数。
以下是一个设置参数的示例中,con表示一个活动连接:
PreparedStatementpstmt=con.prepareStatement("UPDATEEMPLOYEES
SETSALARY=?
WHEREID=?
");
pstmt.setBigDecimal(1,2000.00);
pstmt.setInt(2,100);
pstmt.excuteUpdate();
SQL语句中需要赋值的部分可以用?
代替,然后通过set方法来设置参数。
由于设计参数时不同的类型方法也不同,能够很好的处理不同的类型。
例如在设置日期型的参数时,可以直接通过setDate方法设置参数,而如果通过SQL语句的字符串拼写,则必须对日期进行格式化。
对于复杂的Insert、update和delete的SQL语句,以及需要多次执行而参数不同的SQL语句,使用PreparedStatement具有明显优势。
3.java.sql.ResultSet:
从数据库库提取后的数据保存在ResultSet中,ResultSet提供的getter方法能够方便的返回记录集中的数据。
程序代码设计如下:
packagetest.sample.dao;
importjava.sql.*;
importjava.util.ArrayList;
importjava.util.List;
importtest.sample.bean.Product;
importtest.sample.bean.ProductType;
publicclassProductDao{
//提取商品数据,并转换为商品对象,存储到列表中
publicstaticListgetProductList()throwsException{
Connectionconn=DaoFactory.getConnection();
try{
Statementst=conn.createStatement();
Stringsql="select*fromProduct";
ResultSetrs=st.executeQuery(sql);
Listlist=newArrayList();
while(rs.next()){
Productp=newProduct();
p.setId(rs.getInt("ID"));
p.setName(rs.getString("NAME"));
p.setType(rs.getInt("TYPE"));
p.setCountInBox(rs.getString("COUNT_IN_BOX"));
p.setPrice(rs.getFloat("PRICE"));
p.setStock(rs.getInt("STOCK"));
list.add(p);
}
rs.close();
st.close();
returnlist;
}
finally{
conn.close();
}
}
//将一个商品对象插入到数据库
publicstaticProductInsertProduct(Productp)throwsException{
Connectionconn=DaoFactory.getConnection();
try{
Stringsql="INSERTINTOProduct(NAME,TYPE,COUNT_IN_BOX,PRICE,STOCK)VALUES(?
?
?
?
?
)";
PreparedStatementps=conn.prepareStatement(sql);
ps.setString(1,p.getName());
ps.setInt(2,p.getType());
ps.setString(3,p.getCountInBox());
ps.setFloat(4,p.getPrice());
ps.setInt(5,p.getStock());
ps.executeUpdate();
Statementst=conn.createStatement();
ResultSetrs=st.executeQuery("selectmax(ID)fromProduct");
rs.next();
intid=rs.getInt
(1);
p.setId(id);
rs.close();
st.close();
ps.close();
returnp;
}
finally{
conn.close();
}
}
//将一个商品对象插入到数据库
publicstaticProductupdateProduct(Productp)throwsException{
Connectionconn=DaoFactory.getConnection();
try{
Stringsql="UPDATEProductset
NAME=?
TYPE=?
COUNT_IN_BOX=?
PRICE=?
STOCK=?
whereID=?
";
PreparedStatementps=conn.prepareStatement(sql);
ps.setString(1,p.getName());
ps.setInt(2,p.getType());
ps.setString(3,p.getCountInBox());
ps.setFloat(4,p.getPrice());
ps.setInt(5,p.getStock());
ps.setInt(6,p.getId());
ps.executeUpdate();
ps.close();
returnp;
}
finally{
conn.close();
}
}
//删除一个商品记录
publicstaticbooleandeleteProduct(intid)throwsException{
Connectionconn=DaoFactory.getConnection();
try{
Stringsql="deletefromProductwhereID="+id;
Statementps=conn.createStatement();
booleanb=ps.execute(sql);
ps.close();
returnb;
}
finally{
conn.close();
}
}
//获取商品类型数据,并转换为商品类型对象,存储到列表
publicstaticListgetProductTypeList()throwsException{
Connectionconn=DaoFactory.getConnection();
try{
Statementst=conn.createStatement();
Stringsql="select*fromProductType";
ResultSetrs=st.executeQuery(sql);
Listlist=newArrayList();
while(rs.next()){
ProductTypept=newProductType();
pt.setId(rs.getInt("TYPE_ID"));
pt.setName(rs.getString("TYPE_NAME"));
pt.setRemark(rs.getString("REMARK"));
list.add(pt);
}
rs.close();
st.close();
returnlist;
}
finally{
conn.close();
}
}
}
通过上面的代码我们可以看到,从ProductDao调用方法的对象不需要关系数据库,而只需要知道Product对象即可,无论我们如何修改“商品”数据的存储方法,都不会影响访问对象。
也就是说,我们通过ProductDao对象将对商品表数据的访问完全的封装了。
访问商品数据的对象甚至不知道商品数据是保存在什么样的数据库当中。
这就是面向对象设计的重要特性——封装。
ProductDao对象提供了“商品”数据的提取、插入、删除方法,提供了商品类别的提取方法。
事实上,这不是数据操作的全部,所有涉及商品的数据库操作,都可以放到ProductDao对象中,如修改商品的名称,统计商品的库存等等。
4.建立数据对象
数据对象作为应用程序的数据载体,能够用于数据加工和数据传递,同时由于数据对象是无状态的,因此数据对象的使用能够应用实现更加地灵活。
数据对象(JavaBean)是一种特殊的对象,特殊的是在类的方法命名上遵守以下规则:
1.如果类的成员变量的名字是xxx,那么为了更改或获取成员变量的值,即更改或获取属性,在类中可使用两个方法:
getXxx(),用来获取属性;xxx;setXxx(),用来修改属性xxx.。
2.对于boolean类型的成员变量,即布尔逻辑类型的属性,允许使用"is"代替上面的"get"。
3.类中方法的访问属性都必须是public的。
4.类中如果有构造方法,那么这个构造方法也是public的并且是无参数的。
事实上,这种方式是面向对象设计的一个理念,即封装。
通过get和set方法,将对象的外在表现和内部实现分离,从而为对象的修改和重用提供良好的基础。
例如:
一个方法getName,它的作用是返回对象的名字,作为访问者无需知道这个名字是如何存储的,只需调用方法访问即可。
packagetest.sample.bean;
/**
*商品对象
*/
publicclassProduct{
privateintid;//商品的唯一标识
privateStringname;//商品的名称
privateinttype;//商品的类型内码
privateStringcountInBox;//每箱数量
privatefloatprice;//商品的价格
privateintstock;//库存数量
publicintgetId(){
returnid;
}
publicvoidsetId(intid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetType(){
returntype;
}
publicvoidsetType(inttype){
this.type=type;
}
publicfloatgetPrice(){
returnprice;
}
publicvoidsetPrice(floatprice){
this.price=price;
}
publicStringgetCountInBox(){
returncountInBox;
}
publicvoidsetCountInBox(StringcountInBox){
this.countInBox=countInBox;
}
publicintgetStock(){
returnstock;
}
publicvoidsetStock(intstock){
this.stock=stock;
}
}
我们可以看到,上面的两个数据对象中,都是通过get和set方法对私有属性进行封装。
那么,不使用get和set方法,直接将属性作为公开属性不行吗?
单从程序访问的角度没有问题,我们可以直接访问公开属性,但同时也破坏了数据对象的封装性。
更为重要的是,数据对象这种形式已经广泛的为业界所承认,成为一种规则,绝大部分的开源软件通过get和set这种形式来访问数据,例如Hibernate,spring。
事实上,这种形式不仅仅在java中使用,在主流的面向对象语言中,都采用了这种形式。
5.建立商品列表显示模型和商品类型模型
为了能够将数据对象列表能够以表格(table)的形式进行显示,我们需要为表格显示控件JTable提供一个数据来源。
实现一个AbstractTableModel,能够为JTable控件提供数据,将商品对象列表以表格的形式进行显示。
在Javaswing中以表格形式显示数据的标准控件是JTable,一般的情况下,数据以对象列表或者对象数组的形式存储,表格的每一行显示一个对象的信息,表格的每一列显示对象某个属性的信息。
为了能够方便的使用JTable,Java提供了专门支持它的数据模型TableModel。
TableModel负责将数据整理为JTable显示所需要的形式,是介于基础数据和显示控件之间的代理。
在创建JTable时,可以采用带参数的创建方法,将TableModel作为参数传递给JTable。
JTable的数据显示是通过TableModel进行驱动的,因此修改TableModel中的数据,能够通过调用方法刷新JTable的数据显示。
为了更加方便的处理数据和数据的显示,我们需要从AbstractTableModel类继承,实现自己的TableModel类。
AbstractTableModel是一个抽象数据类型,我们有三个方法必须实现:
publicintgetColumnCount()//获得要显示的数据的列数
publicintgetRowCount() //获得要显示的数据的行数
publicObjectgetValueAt(introw,intcol)//获得一个单元格的数据
以上三个方法的实现可以根据原始数据和显示需求来实现,例如getColumnCount可以根据需要显示的属性的个数确定,getRowCount可以通过数据记录的个数确定。
为了支持对数据的修改操作,我们还可以在TableModel中添加一些数据修改的方法。
packagetest.sample.model;
importjava.util.ArrayList;
importjava.util.List;
importjavax.swing.table.AbstractTableModel;
importtest.sample.bean.Product;
importtest.sample.dao.ProductDao;
publicclassProductModelextendsAbstractTableModel{
privateListpList=newArrayList();
publicvoidloadData()throwsException{
pList=ProductDao.getProductList();
}
//列标题
String[]headers={"商品内码","商品名称","商品类型","单位数量","价格","库存"};
//获得列数
publicintgetColumnCount(){
returnheaders.length;
}
//获得行数
publicintgetRowCount(){
returnpList.size();
}
//获得一个单元格的数据
publicObjectgetValueAt(introw,intcol){
if((row<0)||(row>=pList.size()))return"";
Productp=(Product)pList.get(row);
switch(col){
case0:
returnnewInteger(p.getId());
case1:
returnp.getName();
case2:
returnProductTypeEnum.getTypeName(p.getType());
case3:
returnp.getCountInBox();
case4:
returnnewFloat(p.getPrice());
case5:
returnnewInteger(p.getStock());
}
return"";
}
publicProductgetProduct(introw){
return(Product)pList.get(row);
}
//获得列的名字
@Override
publicStringgetColumnName(intcol){
returnheaders[col];
}
//添加一个商品对象
publicvoidaddProduct(Productp)throwsException{
ProductDao.InsertProduct(p);
pList.add(p);
this.fireTableRowsInserted(pList.size()-1,pList.size()-1);
}
//更新一个商品对象
publicvoidupdateProduct(i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 小型 仓库 管理 系统 详细 设计 实现