SE知识汇总--项目

一:项目简介:

      该项目是一款基于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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值