基于字符界面的收银台

简述:该系统是一款纯字符界面的收银台系统,实现了商品管理,浏览,下单,支付功能。

系统需求:

  • 登录注册
  • 管理端
    用户管理
    商品管理
  • 用户端
    商品浏览
  • 订单管理
    下单支付

具体实现了以下几个功能:

1.公共端:

(1)入口命令 :注册(REGISTER),登录 (LOGIN)
(2)公共命令:关于系统(GYXT), 帮助信息(BZXX), 退出系统(TCXT)

2.管理端:

(1)账户信息:查看账户(CKZH) ,重置密码(CZMM) ,停止账户(QTZH)
(2)商品信息:浏览商品(LLSP),上架商品(SJSP) 下架商品(XJSP) 更新商品(GXSP)
(3)公共命令:关于系统(GYXT), 帮助信息(BZXX), 退出系统(TCXT)

3.用户端:

(1)商品信息:浏览商品(LLSP)
(2)公共命令:关于系统(GYXT), 帮助信息(BZXX), 退出系统(TCXT)
(3)我的订单:查看订单(CKDD),支付订单(ZFDD)

涉及到的技术:

  • 集合框架 :使用Map集合存放不同类型的命令
  • 注解技术:通过注解的方式对命令进行分类
  • MySQL数据库:包含对字段的增删改查和表与表之间的连接等sql语句的编写
  • JDBC编程:采用DataSource方式连接数据库

数据库的设计

实体设计:

account表:

Java小型超市收银系统 java收银台程序_Java小型超市收银系统


goods表:

Java小型超市收银系统 java收银台程序_抽象类_02


order表:

Java小型超市收银系统 java收银台程序_数据库_03


orderItem表:

Java小型超市收银系统 java收银台程序_sql语句_04


(1)账户和商品之间:一个账户可以拥有多个商品,一个商品也可以被多个用户所拥有。

(2)账户和订单之间:一个账户可以有多个订单,但是一个订单只属于一个账户。

(3)订单和订单项之间:一个订单可包含多个订单项

(4)订单项和商品之间:一个订单可能包含多个商品

分层设计

Java小型超市收银系统 java收银台程序_Java小型超市收银系统_05


1.首先在实体类中给四个表中的字段提供属性(和数据库表中各属性的类型一致),并且利用lombok插件,使用@Data注解自动为当前类各属性提供getter和setter以及toString方法,这样我们无须再手动提供,直接可以调用,大大减少了我们的代码量。

2.为了解决不同的用户登录看到的商品信息不一样,我使用了注解,通过注解对命令进行了分类。
建立了以下四个注解:

  • @AdminCommand:****管理端
  • @CommandMeta:
    name:表示你要输入的命令()
    desc:表示对输入命令的提示
    group:表示命令的分组(如:入口命令,公共命令,账号信息等)
  • @CustomerCommand:客户端
  • @EntranceCommand:入口命令

给注解上面再加上@Retention(RetentionPolicy.RUNTIME)注解:使得注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在。
RUNTIME:表明运行之后,信息就会保存在class中,然后通过反射拿到class对象,将命令进行分类存放到不同的map
@Target(ElementType.TYPE)注解:说明了Annotation所修饰的对象范围:用于描述类,接口(包括注解类型)或enum声明。
TYPE:表明注解修饰到类上

3.每个操作命令对应一个类,不同组的命令都有它对应的Service层以及Dao层,我们用Command层操作Service层,然后用Service层去操作Dao层。
(1)建一个接口Command,里面实例化了一个Scanner对象,只要有类实现了Command类就可以调用这个Scanner对象,通过Scanner来读取输入流的信息。还定义了一个统一实现功能的方法。统一方法所观察的对象:subject对象。Subject类得到账户的类型。
(2).因为操作每一个命令都得重启对应的Service层,所以定义了一个抽象类AbstractCommand,在抽象类中t中启动所有的服务。此抽象类实现了Command接口,
command接口里又有统一的操作方法和Scanner对象,然后让每一个命令继承这个抽象类,那么每一个命令都要实现自己的excute方法。

4.通过Dao层操作数据库的
1.在BaseDao中建立数据库的连接,使用datasource的方法连接数据库
每个命令的Dao类都继承BaseDao
使用步骤:
1.拿到连接
2.编写sql语句
3.将Sql语句进行预编译存储到PreparedStatement对象(防止SQL注入漏洞)
4.最终会生成一个ResultSet对象
5.解析resultset结果集,拿到对应的account

项目测试:

1.功能测试

注册功能:输入用户名,密码,姓名,选择账户类型即可完成注册

Java小型超市收银系统 java收银台程序_sql语句_06


登录:输入用户名和密码进行登录,不同的类型的账号进入系统,显示的提示不同,可以完成的功能也不相同

Java小型超市收银系统 java收银台程序_数据库_07


Java小型超市收银系统 java收银台程序_数据库_08


查看账号:管理员可以查看所有账户的信息

Java小型超市收银系统 java收银台程序_数据库_09


重置密码:管理员输入要重置密码的账号的Id和新的密码,可以修改其他账户的密码

Java小型超市收银系统 java收银台程序_数据库_10


停止账号:输入要停止账号的Id,b修改他的状态为unlock(默认为:lock)

Java小型超市收银系统 java收银台程序_抽象类_11


浏览商品:管理员及客户都可以浏览所有的商品

Java小型超市收银系统 java收银台程序_数据库_12


Java小型超市收银系统 java收银台程序_数据库_13


上架商品:只有管理员可以进行商品的上架

Java小型超市收银系统 java收银台程序_sql语句_14


更新商品:管理员可以对已经上架的商品信息进行修改

Java小型超市收银系统 java收银台程序_抽象类_15


下架商品:同样只有管理员可以下架商品

Java小型超市收银系统 java收银台程序_sql语句_16


支付订单:顾客输入一组要买的商品的id及数量,选择支付就可以完成订单的支付

Java小型超市收银系统 java收银台程序_抽象类_17


查看订单:客户可以查看以往自己已经成功支付过的订单

Java小型超市收银系统 java收银台程序_sql语句_18


2.容错性测试:

管理员上架商品时,商品数量输入负数,零或正数时,是否可以上架成功

Java小型超市收银系统 java收银台程序_sql语句_19


可以,但商品数量不应该为负数,所以应该改进一下,在输入数量后先判断一下是否小于0,如果小于零,应上架失败如果某个商品只有3件,但客户想要买4件时,程序该如何处理这种情况呢

Java小型超市收银系统 java收银台程序_Java小型超市收银系统_20


数据库里面的商品库存更新为-1,而当购买数量大于实际库存时,不应该支付成功。

可以先获取要购买商品的数量,如果小于商品实际数量才可以购买。

Java小型超市收银系统 java收银台程序_Java小型超市收银系统_21


如果一个客户一个商品购买了0件,是否可以支付,并生成订单项

Java小型超市收银系统 java收银台程序_数据库_22


其数据依旧会插入数据库,生成一个订单项。

Java小型超市收银系统 java收银台程序_抽象类_23

项目难点:

此项目最难解决的问题就是如何处理订单和订单项

因为顾客可以购买多个商品,那么这一次购物就应该生成一笔订单。所以我建立了两张表order和orderItem。order里面存放该订单的信息,而订单项则存放该订单每个物品的详情。
要想实现支付订单,首先要实现插入订单和插入订单明细:前面的功能都是让它自动提交事务,而插入订单我其设置为手动提交事务,当提交失败时,就使其回滚。
如果要插入多组数据,可以使用addBatch()方法,它可以将批量插入。
最后要记得,支付成功后,商品的库存也要发生变化,所以支付成功后应该更新商品的库存。

项目优化:

1.系统功能优化:
1)基于上面的容错性测试,应该对商品的库存做一些约束,上架商品时商品库存不能为负数,顾客也不能购买比商品库存还多的商品,在顾客购买0件商品时不生成一笔订单。
2)管理员不应该修改其他管理员的密码,也不应该停止其他管理员的账号,所以应该在修改密码功能和停止账号功能先判别一下是普通账号还是管理员账号。使得管理员只可以修改他自己和其他账户的密码,停止普通账户账号的使用。
2.系统界面优化:
此系统是一个基于字符界面的系统,用户在操作系统时视觉体验极差,操作步骤也过于繁琐。可以将此系统改成一个web项目,用户注册、用户登录、商品上架、商品更新都可以用表单来实现。每个命令都用按钮来实现,用户只需要点击按钮就可以操作,不需要输入各种命令。

总结:

这个收银台做的有点简陋,数据表的关系也不难,一开始也遇到了一些困难,因为有管理员和客户两种身份,管理员和用户要显示的界面和要完成的功能也不相同,那么如何区分那些功能是管理端,哪些是用户端,哪些是入口命令呢?后来,我了解到可以利用注解对命令进行分类,这个问题也就迎刃而解了。还有就是订单和订单项之间的关系,一个订单对应多个订单项,可以在订单项表中设置一个字段orderId存放订单的id,两张表联合查询即可得到订单信息。为了防止sql语句上出错,可以在resources中建立一个query_order_by_account.sql,在它里面处理两表关系。