概述
一:项目简介:
该项目是一款基于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后,将其放入池子里,当下次使用的时候从池子里拿出来使用,即重复利用,不会有频繁的创建和销毁。
package 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中处理两个表的连接,在此使用了左连接。
执行语句: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知识汇总--项目一:项目简介:二:功能简介:三:分层设计四:技术实现五:项目总结 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复