一:项目简介:
该项目是一款基于SE知识的字符界面收银台系统,主要实现的功能:客户端(注册登录,浏览商品,下单,支付,修改密码)管理端(注册登录,管理商品,查看账户信息,修改用户密码以及启停账户)
涉及技术:Stream式编程,datasource连接MySQL数据库,注解以及lombok(自动生成get/set方法)的使用,集合框架等。
二:功能简介:
2.1公共端:
2.2客户端:
2.3管理端:
三:分层设计
四:技术实现
4.1数据库:
主表:
order_item表
order表
goods表
account表
4.2各个表之间的关系:
4.3连接数据库:
在BaseDao中建立数据库的连接,此处采用了datasource的方法进行连接
之所以采用datasource的方法,而不用DriverManager的原因:
datasource共有三种类型的实现:
(1)基本实现 - 生成标准的 Connection 对象
(2)连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。
(3)分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。
一个DataSource对象代表了一个真正的数据源,当一个DataSource对象注册到名字服务中,应用程序就可以通过名字服务获得DataSource对象,并用它来产生一个与DataSource代表的数据源之间的连接.它无需硬性编码驱动,而DriverManager需要硬性编码驱动。
因为它有连接池的实现,所以,当每次用完connection后,将其放入池子里,当下次使用的时候从池子里拿出来使用,即重复利用,不会有频繁的创建和销毁。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123package com.cashsystem.dao; /*import com.mysql.jdbc.PreparedStatement; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import javax.activation.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException;*/ import com.mysql.jdbc.PreparedStatement; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import javax.sql.DataSource; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; /** * Created with IntelliJ IDEA * Description: * User:Light_Long * Date:2019-08-04 * Time:16:34 */ public class BaseDao { //连接数据库 private static volatile DataSource dataSource; //采用基本实现 private DataSource getDataSource() { if (dataSource == null) { synchronized(DataSource.class) { if (dataSource == null) { dataSource = new MysqlDataSource();//MySql数据源 String host = "127.0.0.1"; String port = "3306"; ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://" + (host + ":" + port) + "/myfirstproject"); ((MysqlDataSource) dataSource).setUser("root"); ((MysqlDataSource) dataSource).setUseSSL(false); ((MysqlDataSource) dataSource).setPassword("root"); } } } return dataSource; } protected Connection getConnection(boolean autoCommit) throws SQLException { //获取连接 Connection connection = this.getDataSource().getConnection(); //如果true 每写一条语句 自动进行提交 connection.setAutoCommit(autoCommit); return connection; } protected void closeResource(ResultSet resultSet, PreparedStatement statement, Connection connection) { //结果 -> 命令 -> 连接 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } public String getSql(String sqlName) { System.out.println("=====sqlName:"+sqlName); //InputStream 是字节流 try (InputStream in = this.getClass() .getClassLoader() //这个方法是用来获取配置文件的,方法传入的参数是一个路径 .getResourceAsStream("script/" + sqlName.substring(1) + ".sql"); // 从1 开始提取的原因是:sqlName: @query_order_by_account 去掉@符号 ) { if (in == null) { throw new RuntimeException("load sql " + sqlName + " failed"); } else { //InputStreamReader :字节流 通向字符流的桥梁 try (InputStreamReader isr = new InputStreamReader(in); //BufferedReader -> 从字符输入流中读取文本并缓冲字符 BufferedReader reader = new BufferedReader(isr)) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(reader.readLine()); String line; while (( line = reader.readLine()) != null) { stringBuilder.append(" ").append(line); } //System.out.println("value:" + stringBuilder.toString()); return stringBuilder.toString(); } } } catch (IOException e) { throw new RuntimeException("load sql " + sqlName + " failed"); } } }
4.4命令实现:
4.5账号信息模块:
查看账户:
启停账户:
修改密码:
客户端自行修改:
管理端修改:
4.6公共命令模块:
x
关于系统:
帮助信息:
退出系统:
4.7入口命令模块:
登录:
注册:
4.8商品信息模块:
浏览商品:
更新商品:
下架商品:
上架商品:
上架成功:
4.9订单信息模块:
d
浏览订单:
支付订单:
五:项目总结
重点难点分析:(订单和订单项)
实现支付订单,首先要实现插入订单和插入订单明细:
前面的功能都是让它自动提交事务,在OrderDao中,将其设置为手动提交事务,当提交失败时,使其回滚。
在此,调用了 addBatch() :把所有的预编译的语句先全部放好,然后调addBatch批量插入。
因为每次支付完订单之后,商品的数量就会减少,因此,在GoodsDao里提供一个 public boolean updateAfterPay(Goods goods,int goodsNum)方法,然后在支付订单命令里调用,判断库存是否更新。因为订单和订单项之间是一对多的关系,因此在实现查询订单信息时,若直接写sql语句有点麻烦且容易出错,因此如下图所示,在resources中处理两个表的连接,在此使用了左连接。
1执行语句:String sql = this.getSql("@query_order_by_account");
通过这次的项目我对数据库的知识有了更近一步的掌握,在处理多表问题的时候不再慌张,注解的使用也是一次突破,尤其是学到了lombok的使用,使编程更加方便,直接通过maven导入也大大降低了编程难度,函数式编程风格使代码更加清晰明了,一步步的调用更增加了程序的安全性;在与数据库连接时使用了datasource,通过getConnection方法返回逻辑连接;连接对象使用代理模式, 覆盖连接接口的close方法, 用于归还连接; 而且这对jdbc开发者透明, 原来的代码不需要任何改变。在处理订单支付的时候,发现每一次更新数据库都需要重新连接并且更新数据库内容,效率非常低,百度后使用preparedStatement.addBatch();方法,采用缓冲后再一次性更新数据库,这样的效率远比之前要高,算是一次优化。
学习的知识运用到项目之后才发现自己有很多不足,比如数据库知识遗忘的较多,做完项目之后有很大的提升。一次项目的结束是另一个项目的开始,收获这次的经验之后,对于下一次项目的开发会有很大的帮助,写篇博客鼓励自己继续进步,不能停止学习,菜鸟继续加油!!!
项目源码:
https://github.com/180831/0330./commit/93f96a49728404c7d254a40002ff34ba52d67200
最后
以上就是专一铅笔最近收集整理的关于SE知识汇总--项目一:项目简介:二:功能简介:三:分层设计四:技术实现五:项目总结 的全部内容,更多相关SE知识汇总--项目一:项目简介:二:功能简介:三:分层设计四:技术实现五内容请搜索靠谱客的其他文章。
发表评论 取消回复