介绍

系统概述:转转好物交易平台

转转好物交易平台

  • 整体思路

    • 使用MySQL + JDBC实现一个二手交易系统
    • 使用三层架构开发应用
  • 项目分为管理员操作界面和普通用户操作界面

操作界面

  • 主要功能

    • 管理员操作界面
    • 登录
    • 查看好物列表
    • 查看交易记录功能
  • 普通用户操作界面

    • 登录
    • 查看好物列表
    • 上架新的好物
    • 查看我的在售好物
    • 购买

整体开发思路

系统开发步骤

  1. 明确需求
  2. 设计数据库
  3. 设计技术框架

    1. Java技术
    2. 三层架构
  4. 编码顺序

    1. 系统启动
    2. 登入功能
    3. 普通用户操作
    4. 管理员用户操作
  5. 测试

界面交互设计的原则

  • 统一性原则

    • 界面风格统一

      • 用相同方式展现相同类型的数据,如:日期类型
    • 交互风格统一

      • 用相同方式完成相同类型的操作,如:录入日期
  • 美观性原则

    • 界面美观大方
  • 易用性原则

    • 操作方式自然、易理解

使用类图设计系统

  • 采用三层架构搭建系统框架

    • 数据访问层、业务逻辑层、表示层
  • 采用数据访问层采用DAO模式设计和开发

    • 设计步骤

      1. 根据数据库表创建实体
      2. 创建数据访问层DAO接口和实现类
      3. 创建业务逻辑层接口和实现类
      4. 创建表示层

设计并创建数据库表

  • 数据库表

    • 普通用户信息表(user)
    • 管理员信息表( admin)
    • 好物信息表( goods)
    • 好物类别表( type)
    • 交易记录表( tradelog)

数据库设计

外键实际不用建 用java代码约束就行不然开发后期麻烦

设计数据库表结构

  • 根据业务确定表的名称
  • 根据业务确定表的具体字段

    • 如何区分一个好物是否被卖出
    • 如何在交易记录中确定买家和卖家
    • 如何确定一个好物是属于哪个卖家的
  • 注意主键和外键的设计,建立表之间关联关系

新建数据库

SQL语句

/*
 Navicat Premium Data Transfer

 Source Server         : mysql
 Source Server Type    : MySQL
 Source Server Version : 80029
 Source Host           : localhost:3306
 Source Schema         : zhuanzhuandb

 Target Server Type    : MySQL
 Target Server Version : 80029
 File Encoding         : 65001

 Date: 08/11/2022 08:33:00
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for admin
-- ----------------------------
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of admin
-- ----------------------------
INSERT INTO `admin` VALUES (1, 'root', '123456');

-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `price` float NULL DEFAULT NULL,
  `description` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `addTime` datetime NULL DEFAULT NULL,
  `isOnSell` tinyint(1) NULL DEFAULT NULL,
  `typeID` int NOT NULL,
  `ownerID` int NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `typeID`(`typeID`) USING BTREE,
  INDEX `ownerID`(`ownerID`) USING BTREE,
  CONSTRAINT `goods_ibfk_1` FOREIGN KEY (`typeID`) REFERENCES `type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `goods_ibfk_2` FOREIGN KEY (`ownerID`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, '樱花暖手宝', 110, '暖手宝+充电宝,10000mAh', '2021-03-05 12:23:23', 0, 1, 2);
INSERT INTO `goods` VALUES (2, '么么哒潮牌焖烧杯', 120, '304不锈钢+PP+硅胶', '2021-03-02 08:45:11', 0, 1, 2);
INSERT INTO `goods` VALUES (3, '皇冠猴手机支架', 12, '可爱立体支架,车载使用', '2021-03-02 16:56:00', 1, 1, 1);
INSERT INTO `goods` VALUES (4, '迷你潜水艇加湿器', 60, '自带电池,智能显示,长时续航', '2021-03-04 20:30:12', 1, 1, 2);
INSERT INTO `goods` VALUES (5, '流氓兔系列蓝牙耳机', 105, '够小够轻,无负担佩戴一整天', '2021-03-01 19:20:12', 1, 1, 2);
INSERT INTO `goods` VALUES (6, '藏银手链', 340, '精工,复工,朋克', '2021-03-02 14:34:12', 1, 2, 3);
INSERT INTO `goods` VALUES (7, '藏银耳钉', 234, '硫化做旧特殊星光', '2021-03-03 15:11:45', 1, 2, 3);
INSERT INTO `goods` VALUES (8, '手工油纸伞', 123.4, '传统工艺,拍照必备', '2021-03-15 05:48:29', 1, 2, 1);
INSERT INTO `goods` VALUES (9, '小狗', 43.4, '已经断奶,会上厕所', '2021-03-15 13:52:15', 1, 3, 1);
INSERT INTO `goods` VALUES (10, '小仓鼠', 12, '1岁大的小仓鼠', '2021-03-15 21:58:52', 1, 3, 1);
INSERT INTO `goods` VALUES (11, '小鸡手机壳', 5, '可爱漂亮的小鸡手机壳', '2021-03-18 17:18:48', 1, 2, 1);

-- ----------------------------
-- Table structure for tradelog
-- ----------------------------
DROP TABLE IF EXISTS `tradelog`;
CREATE TABLE `tradelog`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `buyerID` int NOT NULL,
  `goodsID` int NOT NULL,
  `sellerID` int NOT NULL,
  `tradeTime` datetime NULL DEFAULT NULL,
  `receiveInfo` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `buyerID`(`buyerID`) USING BTREE,
  INDEX `goodsID`(`goodsID`) USING BTREE,
  INDEX `sellerID`(`sellerID`) USING BTREE,
  CONSTRAINT `tradelog_ibfk_1` FOREIGN KEY (`buyerID`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `tradelog_ibfk_2` FOREIGN KEY (`goodsID`) REFERENCES `goods` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `tradelog_ibfk_3` FOREIGN KEY (`sellerID`) REFERENCES `goods` (`ownerID`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of tradelog
-- ----------------------------
INSERT INTO `tradelog` VALUES (1, 1, 1, 2, '2021-03-16 10:54:41', '北京');
INSERT INTO `tradelog` VALUES (2, 1, 2, 2, '2021-03-18 16:59:12', '上海');

-- ----------------------------
-- Table structure for type
-- ----------------------------
DROP TABLE IF EXISTS `type`;
CREATE TABLE `type`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of type
-- ----------------------------
INSERT INTO `type` VALUES (1, '创意好物');
INSERT INTO `type` VALUES (2, '精致手作');
INSERT INTO `type` VALUES (3, '奇趣宠物');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `balance` float NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '乐乐', '123456', 330);
INSERT INTO `user` VALUES (2, '小峰', '234557', 400);
INSERT INTO `user` VALUES (3, '妮妮', 'nn12345', 790);
INSERT INTO `user` VALUES (4, '茵茵', 'yy54321', 270);

SET FOREIGN_KEY_CHECKS = 1;

脚本下载:https://www.aliyundrive.com/s/nitwu6B22yj

提示

数据库中插入语句的错误提示

数据库插入语句错误提示

图中 near 提示了错误的地方在NOT上所以应该在NOT后面加上NULL

搭建系统三层架构

根据数据库表创建实体类

  • 实体类一般和数据库表对应,实体类的属性对应于表的字段
  • 为五个数据库表分别创建实体类,实现数据库数据在各个层次的传输
  • 五个实体类的名称可以定义为User、Admin、Goods、Type、Tradelog

实体类

根据业务需求创建VO(Value Object)

  • 显示数据时,数据可能来源于多张数据库表

    • 交易记录表(tradelog)通过外键的方式与好物信息表(goods)中记录相关联
  • 实际开发使用VO及表示层对象实现在业务层之间传递数据
  • VO可以和表对应,也可以不对应,这主要取决于业务的需求
  • 创建用于表示层的好物信息和交易记录信息的VO

    • GoodsDetail
    • TradelogDetail

OVpng

创建数据访问层DAO接口和实现类

  • DAO接口

    • UserDao,AdminDao,GoodsDao,TypeDao,TradelogDao
  • 实现类

    • UserDaoImpl,AdminDaoImpl,GoodsDaoImpl,TypeDaoImpl,TradelogDaoImpl
  • BaseDao

    • 定义建立和关闭数据库的代码以及数据插入及更新的代码

DAO接口和实现类

创建业务逻辑层接口和实现类

  • 从业务角度考虑,主要是普通用户和管理员用户的业务
  • 创建普通用户和管理员用户业务接口及实现类
  • 在业务实现类中调用DAO接口实现相应业务

创建业务逻辑层接口和实现类

创建表示层

  • 系统的主流程菜单
  • 提示用户输入数据
  • 系统反馈的信息或数据

分析(登入)

  • DAO代码

    • AdminDao:getAdminByNameAndPwd()查询管理员信息
    • UserDao : getUserByNameAndPwd()查询普通用户信息
  • Service代码

    • AdminService :login()管理员登录
    • UserService : login()普通用户登录
  • 测试类

    • main(): 调用startup() ,启动程序
    • startup():调用login()

      • 管理员登录调用showAdminMenu()方法
      • 普通用户登录调用showUserMenu()方法

需求

  • 管理员用户和普通用户均有查看好物列表及好物详情功能
  • 显示好物列表后,输入好物编号可以查看好物的详情

好物列表

查看好物

分析(好物)

  • VO

    • GoodsDetail:数据来自goods、type、user三张表
  • DAO代码

    • GoodsDao:listOnSellGoods() 返回GoodsDetail列表
  • Service代码

    • AdminService

      • listGoods()显示好物列表
      • showGoodsDetail()显示好物详情
  • UserService

    • listGoods()显示好物列表
    • howGoodsDetail()显示好物详情

提示

  • 好物列表只展示状态为上架在售的好物

    • 在查询数据时应添加上必要的筛选条件
  • 好物列表展示

    • 由于好物数量可能会很多,在查看时需要分页显示
  • 分页显示需要解决的边界值问题

    • 在首页执行上一页和尾页执行下一页要给出适当的提示
  • 好物列表中的编号与数据库中Goods表的id字段不同

    • 好物列表中编号结合当前页码获得好物的对象

分析(好物)

  • DAO代码

    • GoodsDao:updateGoodsOnSellState()更新好物状态
    • UserDao

      • addBalance()卖家增加余额
      • minusBalance()买家减少余额
    • TradelogDao:addTradelog()添加交易流水
  • Service代码

    • UserService:buyGoods()执行购买操作

购买好物

功能测试

  • 用户在余额大于好物价格的条件下成功购买好物
  • 用户在余额小于好物价格的条件下购买好物失败
  • 用户在选择购购买自己上架的好物时购买失败

上架好物和查看用户在售好物功能

  • 用户可以上架新的好物
  • 上架好物后通过“查看我的在售好物”功能看到新上架的好物

上架好物

新好物

  • 用户能上架新的好物
  • 用户能通过查看在售好物功能,查看新上架的好物是否在列表中

实现查看交易记录功能

  • 需求说明

    • 管理员具有查看交易记录的功能

提示

交易记录数据来自于多张数据表,因此使用VO中TradelogDetail类更加合适

技能总结

  • 技术实现

    • 使用三大范式进行规范的关系型数据库设计
    • 使用SQL语句创建数据库、表
    • 使用SQL语句对数据增删改查及子查询
    • 创建数据库用户并授予相应权限
    • Java程序中使用JDBC操作数据库
    • 使用DAO模式封装数据访问代码
    • 使用三层架构开发应用程序
  • 项目流程

    • 需求>设计>开发>测试

以下代码与上面需求如若有差,请谅解。

项目结构

项目结构

数据库连接基类

package dao;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

//数据库连接基类
public class BaseDao {
    private static String driver;
    private static String url;
    private static  String user;
    private static String pwd;
    Connection conn = null;

    static {
        init();
    }
    //从配置文件database.properties里读取数据库连接信息
    private static void init(){
        //创建了一个Properties类引用properties 指向new Properties()对象
        Properties properties = new Properties();
        //使用ClassLoader加载properties配置文件生成对应的输入流
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("Properties/database.properties");
        //异常处理
        try {
            //使用properties对象加载输入流
            properties.load(is);
            //输入或输出发现异常
        }catch (IOException e){
            //捕获异常后抛出
            e.printStackTrace();
        }
        //properties.getProperty方法将搜索此属性列表中指定键的属性值。如果在属性列表中,默认属性列表及其默认值找到了键,然后检查递归。如果未找到该属性的方法返回null
        //读取properties文件代码
        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        user = properties.getProperty("username");
        pwd = properties.getProperty("password");
    }

    /**
     * 获取数据库连接
     * @return
     */
    public Connection getConnection(){
        //声明一个连接对象用来获取数据库连接 名为con 为null
        Connection con = null;
        try {
            //加载驱动
            Class.forName(driver);
            //con 获取数据库连接 取 url,user,pwd的值
            con = DriverManager.getConnection(url,user,pwd);
            //异常处理
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }
        //返回数据库连接
        return con;
    }


    /**
     * 增删改通用方法
     * @param sql
     * @param objs
     * @return int
     */
    public int edit(String sql, Object... objs) {
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        int count = 0;
        try {
            pstmt = conn.prepareStatement(sql);
            // 填充占位符
            if (objs != null) {
                for (int i = 0; i < objs.length; i++) {
                    pstmt.setObject(i + 1, objs[i]);
                }
            }
            // 执行sql语句
            count = pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(null, pstmt, conn);
        }
        return count;
    }

    /**
     * 增、删、改的操作
     * @param preparedSql 预编译的 SQL 语句
     * @param param 参数的字符串数组
     * @return 影响的行数
     */
    public int exceuteUpdate (String preparedSql, Object[] param) {
        PreparedStatement pstmt = null;
        int num = 0;
        conn =  getConnection();
        try {
            pstmt = conn.prepareStatement(preparedSql);
            if (param != null) {
                for (int i = 0; i < param.length; i++) {
                    //为预编译sql设置参数
                    pstmt.setObject(i + 1, param[i]);
                }
            }
            num = pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally{
            closeAll((ResultSet) conn,pstmt,null);
        }
        return num;
    }

    /**
     * 批量增删改通用方法
     * @param sql SQL语句
     * @param listObjs 存放Object数组的list集合 Object数组要修改的数据
     * @return int[] 受影响数组
     */
    public int[] batchEdit(String sql, List<Object[]> listObjs) {
        Connection conn = getConnection(); // 获取数据库连接对象
        PreparedStatement pstmt = null; // 定义语句对象
        int[] counts = null;
        try {
            conn.setAutoCommit(false);// 关闭自动提交
            pstmt=conn.prepareStatement(sql);
            // 获取ParameterMetaData参数元数据
            ParameterMetaData pmData = pstmt.getParameterMetaData();
            // 获取sql参数的数量-问号的数量
            int parameterCount = pmData.getParameterCount();
            //循环历遍需要添加的几条数据
            for (int j = 0; j < listObjs.size(); j++) {
                //循环历遍问号
                for (int i = 0; i < parameterCount; i++) {
                    //添加对应数据
                    pstmt.setObject(i + 1, listObjs.get(j)[i]);
                }
                //把sql语句存储至批量池
                pstmt.addBatch();
            }
            counts = pstmt.executeBatch();
            conn.commit();// 提交数据
            pstmt.clearBatch();//清除批量池数据
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(null, pstmt, conn);
        }
        return counts;
    }

    /**
     * 通用查询 返回一个对象
     * @param <T>
     * @param sql
     * @param obj
     * @param clazz
     * @return
     */
    public <T>Object queryObj(String sql, Object[] obj, Class<T> clazz){
        // 获取数据库连接
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        ParameterMetaData pmData;
        ResultSet rs = null;
        ResultSetMetaData rmData;
        T t =null;
        try {
            // 获取PreparedStatement对象
            pstmt = conn.prepareStatement(sql);
            // 获取ParameterMetaData参数元数据
            pmData = pstmt.getParameterMetaData();
            // 获取sql参数的数量-问号的数量
            int parameterCount = pmData.getParameterCount();
            // 给参数赋值
            for (int i = 0; i < parameterCount; i++) {
                pstmt.setObject(i + 1, obj[i]);
            }
            // 执行sql语句
            rs = pstmt.executeQuery();
            // 获取ResultSetMetaData结果集元数据
            rmData = rs.getMetaData();
            // 通过结果集元数据获取字段数量
            int columnCount = rmData.getColumnCount();
            // 每循环一个代表查询出一条数据,封装一个javabean对象
            t = clazz.newInstance();
            while (rs.next()) {
                for (int i = 0; i < columnCount; i++) {
                    // 通过字段序号获取字段名称
                    String columnName = rmData.getColumnLabel(i + 1);
                    // 通过字段序号获取字段数据
                    Object value = rs.getObject(i + 1);
                    if(value instanceof Date){
                        value = ((Date)value).toLocalDate();
                    }
                    // 结果赋值给javabean对象
                    Field declaredField = clazz.getDeclaredField(columnName);
                    declaredField.setAccessible(true);
                    declaredField.set(t, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(rs, pstmt, conn);
        }
        return t;
    }

    /**
     * 结果集元数据编写查找通用方法
     * @param sql sql语句
     * @param obj Object[]数组
     * @param clazz Class<T>对象
     * @return List<T> 返回指定类型集合
     */
    public <T>List<T> query(String sql, Object[] obj, Class<T> clazz) {
        // 创建List保存要查询的数据
        List<T> list = new ArrayList<>();
        // 获取数据库连接
        Connection conn = getConnection();
        PreparedStatement pstmt = null;
        ParameterMetaData pmData;
        ResultSet rs = null;
        ResultSetMetaData rmData;
        try {
            // 获取PreparedStatement对象
            pstmt = conn.prepareStatement(sql);
            // 获取ParameterMetaData参数元数据
            pmData = pstmt.getParameterMetaData();
            // 获取sql参数的数量-问号的数量
            int parameterCount = pmData.getParameterCount();
            // 给参数赋值
            for (int i = 0; i < parameterCount; i++) {
                pstmt.setObject(i + 1, obj[i]);
            }
            // 执行sql语句
            rs = pstmt.executeQuery();
            // 获取ResultSetMetaData结果集元数据
            rmData = rs.getMetaData();
            // 通过结果集元数据获取字段数量
            int columnCount = rmData.getColumnCount();
            // 每循环一个代表查询出一条数据,封装一个javabean对象
            while (rs.next()) {
                T t = clazz.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    // 通过字段序号获取字段名称
                    String columnName = rmData.getColumnLabel(i + 1);
                    // 通过字段序号获取字段数据
                    Object value = rs.getObject(i + 1);
                    if(value instanceof Date){
                        value = ((Date)value).toLocalDate();
                    }
                    // 结果赋值给javabean对象
                    Field declaredField = clazz.getDeclaredField(columnName);
                    declaredField.setAccessible(true);
                    declaredField.set(t, value);
                }
                // 将javabean保存到List
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(rs, pstmt, conn);
        }
        return list;
    }



    /**
     * 释放内存
     */
    public void closeAll(ResultSet rs, PreparedStatement pstm , Connection conn){
        if (rs !=null){
            try {
                rs.close();
            }catch (SQLException e){
                e.printStackTrace();
            }finally {
                rs = null;
            }
        }
        if (pstm != null){
            try {
                pstm.close();
            }catch (SQLException e){
                e.printStackTrace();
            }finally {
                pstm = null;
            }
        }
        if (conn != null){
            try {
                conn.close();
            }catch (SQLException e){
                e.printStackTrace();
            }finally {
                conn = null;
            }
        }
    }

}

DAO接口


/**
 * 管理用户(DAO接口)
 */
public interface AdminDao {
    public Admin getAdminByNameAndPwd(String name,String pwd);
}

/**/



/**
 * 好物(DAO接口)
 */
public interface GoodsDao {
    public List<GoodsDetail> listOnSellGoods(int page,int type);
    public List<GoodsDetail> listOnSellGoodsByUserID(int userID, int page);
    public int getOnSellGoodsCountByType(int type);
    public int getOnSellGoodsCountByUserID(int userID);
    public int addNewGoods(Goods goods);
    public int updateGoodsOnSellState(int GoodsID, boolean isOnSell);
}

/**/



/**
 * 交易记录(DAO接口)
 */
public interface TradelogDao {
   public int addTradelog(Tradelog tradelog);
   public List<TradelogDetail> getTradelogs();
}

/**/


/**
 * 好物类型(DAO接口)
 */
public interface TypeDao {
    public List<Type> getTypeList();
}

/**/


/**
 * 普通用户(DAO接口)
 */
public interface UserDao {
    public User getUserByNameAndPwd(String userName,String userPassword);
    public int addBalance(int userID, float change);
    public int minusBalance(int userID, float change);
}

实现类

管理员信息

package dao.dab_interface;

import dao.AdminDao;
import dao.BaseDao;
import entity.Admin;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * 管理员信息(实现类)
 */
public class AdminDaoMySQLImp extends BaseDao implements AdminDao {

    /**
     * 通过用户名和密码获取管理员对象
     * @param name 名称
     * @param pwd   密码
     * @return  给实体类对象
     */
    @Override
    public Admin getAdminByNameAndPwd(String name, String pwd) {
        //声明连接对象为null
        Connection conn = null;
        //声明预编译对象为null
        PreparedStatement pstmt = null;
        //声明结果集对象为null
        ResultSet rs = null;
        //创建实体类
        Admin admin = null;

        //获取数据库连接
        conn = getConnection();
        try {
            //构造PreparedStatement对象
            //SQL语句:查询admin表里的全部名称与密码s
            String sql = "SELECT * FROM admin WHERE name = ? AND password = ?";
            //开始执行SQL语句,并把结果赋值给pstmt
            pstmt = conn.prepareStatement(sql);
            //第一个?号对应name这个参数
            pstmt.setString(1, name);
            //第二个?号对应name这个参数
            pstmt.setString(2, pwd);

            //返回查询结果并把结果赋值给rs
            rs = pstmt.executeQuery();
            //验证用户名和密码
            if (rs.next()) {
                //从MySQL读取用户信息,并加载到patient对象中
                admin = new Admin();
                admin.setName(name);
                //通过列名获得查询结果集中的某一列的值
                admin.setId(rs.getInt("id"));
            }
            //异常处理
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return admin;
    }
}

好物信息

package dao.dab_interface;

import dao.BaseDao;
import dao.GoodsDao;
import entity.Goods;
import vo.GoodsDetail;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 好物(实现类)
 */
public class GoodsDaoMySQLImpl extends BaseDao implements GoodsDao {
    /**
     * 获取在售的好物信息
     *
     * @param page
     * @param type
     * @return
     */
    @Override
    public List<GoodsDetail> listOnSellGoods(int page, int type) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<GoodsDetail> listGoods = new ArrayList<GoodsDetail>();

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String filterType = "";
            //判断是否需要按好物类型查询
            if (type != -1) {
                filterType = "AND typeID = ?";
            }
            String sql = "SELECT goods.id,goods.name,price,description,addTime,type.name as typeName,user.name as ownerName,ownerID FROM goods JOIN user ON goods.ownerID = user.id JOIN type ON goods.typeID = type.id  WHERE isOnSell = true" + filterType + " limit ?,5; ";
            pstmt = conn.prepareStatement(sql);
            //查询条件不同,参数个数不同
            if (type != -1) {
                pstmt.setInt(1, type);
                pstmt.setInt(2, 5 * page);
            } else {
                pstmt.setInt(1, 5 * page);
            }
            rs = pstmt.executeQuery();
            //读取好物信息
            while (rs.next()) {
                GoodsDetail goods = new GoodsDetail();
                goods.setName(rs.getString("name"));
                goods.setPrice(rs.getFloat("price"));
                goods.setDescription(rs.getString("description"));
                goods.setAddTime(rs.getDate("addTime"));
                goods.setType(rs.getString("typeName"));
                goods.setOwner(rs.getString("ownerName"));
                goods.setOwnerID(rs.getInt("ownerID"));
                goods.setId(rs.getInt("id"));
                listGoods.add(goods);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return listGoods;
    }

    /**
     * 按照所有者ID获取好物列表
     *
     * @param userID
     * @param page
     * @return
     */
    @Override
    public List<GoodsDetail> listOnSellGoodsByUserID(int userID, int page) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<GoodsDetail> listGoods = new ArrayList<GoodsDetail>();

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String sql = "SELECT goods.id,goods.name,price,description,addTime,type.name as typeName,user.name as ownerName,ownerID FROM goods JOIN user ON goods.ownerID = user.id JOIN type ON goods.typeID = type.id  WHERE isOnSell = true AND ownerID=? limit ?,5; ";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, userID);
            pstmt.setInt(2, 5 * page);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                GoodsDetail goods = new GoodsDetail();
                goods.setName(rs.getString("name"));
                goods.setPrice(rs.getFloat("price"));
                goods.setDescription(rs.getString("description"));
                goods.setAddTime(rs.getDate("addTime"));
                goods.setType(rs.getString("typeName"));
                goods.setOwner(rs.getString("ownerName"));
                goods.setOwnerID(rs.getInt("ownerID"));
                goods.setId(rs.getInt("id"));
                listGoods.add(goods);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return listGoods;
    }

    /**
     * 获取在售好物的个数
     *
     * @param type
     * @return
     */
    @Override
    public int getOnSellGoodsCountByType(int type) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int goodsCount = 0;

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String filterType = "";
            if (type != -1) {
                filterType = " AND  typeID  = ?";
            }
            String sql = "SELECT count(id) FROM goods WHERE isOnSell = true" + filterType;
            pstmt = conn.prepareStatement(sql);
            if (type != -1) {
                pstmt.setInt('1', type);
            }
            rs = pstmt.executeQuery();
            if (rs.next()) {
                goodsCount = rs.getInt(1);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return goodsCount;
    }

    /**
     * 获取指定用户在售好物个数
     * @param userID
     * @return
     */
    @Override
    public int getOnSellGoodsCountByUserID(int userID) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int goodsCount = 0;

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String sql = "SELECT count(id) FROM goods WHERE isOnSell = true AND ownerID=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, userID);
            rs = pstmt.executeQuery();
            if(rs.next()){
                goodsCount = rs.getInt(1);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return goodsCount;
    }

    /**
     * 上架新的好物
     *
     * @param goods
     * @return
     */
    @Override
    public int addNewGoods(Goods goods) {
        //构造SQL语句
        String preparedSQL = "INSERT goods (name,price,description,addTime,isOnSell,typeID,ownerID) VALUES (?,?,?,?,?,?,?)";
        //构造SQL执行参数数组
        List<Object> params = new ArrayList<Object>();
        params.add(goods.getName());
        params.add(goods.getPrice());
        params.add(goods.getDescription());
        params.add(goods.getAddTime());
        params.add(goods.isOnSell());
        params.add(goods.getTypeID());
        params.add(goods.getOwnerID());
        //调用BaseDao中的更新
        return exceuteUpdate(preparedSQL, params.toArray());
    }

    /**
     * 更新好物信息
     * @param GoodsID
     * @param isOnSell
     * @return
     */
    @Override
    public int updateGoodsOnSellState(int GoodsID, boolean isOnSell) {
        //构造SQL语句
        String preparedSQL = "UPDATE goods SET isOnSell = ? WHERE id = ?";
        //构造SQL执行参数数组
        List<Object> params = new ArrayList<Object>();
        params.add(isOnSell);
        params.add(GoodsID);
        //调用BaseDao中的更新
        return exceuteUpdate(preparedSQL, params.toArray());
    }
}

交易记录

package dao.dab_interface;

import dao.BaseDao;
import dao.TradelogDao;
import entity.Tradelog;
import vo.TradelogDetail;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 交易记录(实现类)
 */
public class TradelogDaoMySQLImpl extends BaseDao implements TradelogDao {
    /**
     * 添加交易记录
     * @param tradelog
     * @return
     */
    @Override
    public int addTradelog(Tradelog tradelog) {
        //构造SQL语句
        String preparedSQL = "INSERT INTO tradelog (buyerID,sellerID,goodsID,tradeTime,receiveInfo) VALUES (?,?,?,?,?)";
        //构造SQL执行参数数组
        List<Object> params = new ArrayList<Object>();
        params.add(tradelog.getBuyerID());
        params.add(tradelog.getSellerID());
        params.add(tradelog.getGoodsID());
        params.add(tradelog.getTradeTime());
        params.add(tradelog.getReceiveInfo());

        //调用BaseDao中的更新
        return exceuteUpdate(preparedSQL, params.toArray());
    }

    /**
     * 获取交易记录
     * @return
     */
    @Override
    public List<TradelogDetail> getTradelogs() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<TradelogDetail> tradelogs = new ArrayList<TradelogDetail>();

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String sql = "SELECT tradelog.id,buyerID,goodsID,sellerID,tradeTime,receiveInfo," +
                    "us1.name AS sellerName, us2.name AS buyerName, goods.name, goods.price FROM tradelog " +
                    "JOIN user AS us1 ON tradelog.sellerID = us1.id " +
                    "JOIN user AS us2 ON tradelog.buyerID =us2.id " +
                    "JOIN goods ON tradelog.goodsID = goods.id;";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            //验证用户名和密码
            while(rs.next()){
                //从MySQL读取用户信息,并加载到patient对象中
                TradelogDetail tradelog= new TradelogDetail();
                tradelog.setId(rs.getInt("id"));
                tradelog.setBuyerID(rs.getInt("buyerID"));
                tradelog.setGoodsID(rs.getInt("goodsID"));
                tradelog.setSellerID(rs.getInt("sellerID"));
                tradelog.setTradeTime(rs.getDate("tradeTime"));
                tradelog.setReceiveInfo(rs.getString("receiveInfo"));
                tradelog.setSellerName(rs.getString("sellerName"));
                tradelog.setBuyerName(rs.getString("buyerName"));
                tradelog.setGoodsName(rs.getString("name"));
                tradelog.setPrice(rs.getFloat("price"));
                tradelogs.add(tradelog);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return tradelogs;
    }
}

好物类型

package dao.dab_interface;

import dao.BaseDao;
import dao.TypeDao;
import entity.Type;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 好物类型(实现类)
 */
public class TypeDaoMySQLImpl extends BaseDao implements TypeDao {
    /**
     * 获取好物类型列表
     * @return
     */
    @Override
    public List<Type> getTypeList() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<Type> types = new ArrayList<Type>();

        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String sql = "SELECT * from type;";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            //验证用户名和密码
            while(rs.next()){
                Type type= new Type();
                type.setId(rs.getInt("id"));
                type.setName(rs.getString("name"));
                types.add(type);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭数据库连接
            closeAll(rs, pstmt, conn);
        }
        return types;
    }
}

普通用户

package dao.dab_interface;

import dao.BaseDao;
import dao.UserDao;
import entity.User;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 普通用户(实现类)
 */
public class UserDaoMySQLImpl extends BaseDao implements UserDao {


    /**
     * 通过用户名和密码获取用户信息
     * @param userName
     * @param userPassword
     * @return
     */
    @Override
    public User getUserByNameAndPwd(String userName, String userPassword) {
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        User user = null;
        conn = getConnection();
        try {
            //构造PreparedStatement对象
            String sql = "SELECT * FROM user WHERE name=? AND password = ?";
            pstm = conn.prepareStatement(sql);
            pstm.setString(1,userName);
            pstm.setString(2,userPassword);
            rs = pstm.executeQuery();
            if (rs.next()){
                //从MySQL读取用户信息,并加载到user对象中
                user = new User();
                user.setName(userName);
                //普通用户编号
                user.setUserID(rs.getInt("id"));
                //普通用户余额
                user.setBalance(rs.getFloat("balance"));
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            //关闭数据库
            closeAll(rs,pstm,conn);
        }
        return user;
    }

    @Override
    public int addBalance(int userID, float change) {

        return 0;
    }

    @Override
    public int minusBalance(int userID, float change) {
        return 0;
    }
}

公共类

管理员

package service.impl;

import dao.AdminDao;
import dao.GoodsDao;
import dao.TradelogDao;
import dao.dab_interface.AdminDaoMySQLImp;
import dao.dab_interface.GoodsDaoMySQLImpl;
import dao.dab_interface.TradelogDaoMySQLImpl;
import entity.Admin;
import entity.Goods;
import service.AdminService;
import vo.GoodsDetail;
import vo.TradelogDetail;

import java.util.List;
import java.util.Scanner;

public class AdminServiceImpl implements AdminService {

    /**
     * 管理员登入
     * @param name
     * @param pwd
     * @return
     */
    @Override
    public Admin login(String name, String pwd) {
        //创建DAO对象
        AdminDao adminDao = new AdminDaoMySQLImp();
        Admin admin = adminDao.getAdminByNameAndPwd(name, pwd);
        return admin;
    }

    /**
     * 显示交易记录
     */
    @Override
    public void listTradeLog() {
        //创建DAO对象
        TradelogDao tradelogDao = new TradelogDaoMySQLImpl();
        //创建集合
        List<TradelogDetail> tradelogs = null;
        tradelogs = tradelogDao.getTradelogs();
        System.out.println("序号\t交易编号\t名称\t价格\t卖家\t买家\t交易时间");
        for (int i = 0; i < tradelogs.size(); i++) {
            TradelogDetail tradelog = tradelogs.get(i);
            System.out.println(i + 1 + "\t" +
                    tradelog.getId() + "\t" +
                    tradelog.getGoodsName() + "\t" +
                    tradelog.getPrice() + "\t" +
                    tradelog.getSellerName() + "\t" +
                    tradelog.getBuyerName() + "\t" +
                    tradelog.getTradeTime() + "\t");
        }
    }

    /**
     * 显示好物信息
     * @param type
     */
    @Override
    public void listGoods(int type) {
        int curPage = 0;
        //创建DAO对象
        GoodsDao goodsDao = new GoodsDaoMySQLImpl();
        Scanner input = new Scanner(System.in);
        boolean isShowGoods = true;
        List<GoodsDetail> listGoods = null;
        do {
            if (isShowGoods) {
                listGoods = goodsDao.listOnSellGoods(curPage, type);
                showListGoods(listGoods, curPage);
            }
            int pageCounts = (int) Math.ceil(goodsDao.getOnSellGoodsCountByType(type) / 5.0);
            //判断当前页是否为最后一页
            boolean hasLastPage = pageCounts > curPage + 1;
            System.out.println("1.查看好物详情\t2.上一页\t3.下一页\t0.返回上一级");
            System.out.print("请输入要执行的操作:");
            String action = input.next();
            //查看好物
            if (action.equals("1")) {
                System.out.println("请输入要查看的好物编号");
                //计算好物在列表里面的索引
                int index = Integer.valueOf(input.next()) - curPage * 5;
                if (index <= listGoods.size() && index >= 1) {
                    GoodsDetail godds = listGoods.get(index - 1);
                    showGoodsDetail(godds);
                    break;
                } else {
                    System.out.println("好物编号输入错误!");
                }
                //显示上一页
            } else if (action.equals("2")) {
                //当前页不是首页的情况
                isShowGoods = curPage > 0;
                if (isShowGoods) {
                    curPage--;
                } else {
                    System.out.println("已到首页,无法向前翻页!");
                }
            } else if (action.equals("0")) {
                break;
            } else {
                System.out.println("输入错误,请重新输入");
            }
        } while (true);

    }

    private void showListGoods(List<GoodsDetail> listGoods, int curPage) {
        System.out.println("编号\t名称\t价格\t上架时间");
        for (int i = 0; i < listGoods.size(); i++) {
            GoodsDetail goods = listGoods.get(i);
            //显示的编号当前页码有关
            int index = curPage * 5 + i + 1;
            System.out.println(index + "\t" +
                    goods.getName() + "\t" +
                    goods.getPrice() + "\t" +
                    goods.getAddTime() + "\t");
        }

    }


    private void showGoodsDetail(GoodsDetail goods) {
        System.out.println("好物名称" + goods.getName());
        System.out.println("好物类型" + goods.getType());
        System.out.println("好物价格" + goods.getPrice());
        System.out.println("好物主人" + goods.getOwner());
        System.out.println("好物介绍" + goods.getDescription());
        System.out.println("上架时间" + goods.getAddTime());
    }
}

普通用户

package service.impl;

import dao.GoodsDao;
import dao.TradelogDao;
import dao.TypeDao;
import dao.UserDao;
import dao.dab_interface.GoodsDaoMySQLImpl;
import dao.dab_interface.TradelogDaoMySQLImpl;
import dao.dab_interface.TypeDaoMySQLImpl;
import dao.dab_interface.UserDaoMySQLImpl;
import entity.Goods;
import entity.Tradelog;
import entity.Type;
import entity.User;
import service.UserService;
import vo.GoodsDetail;

import javax.swing.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.TimeZone;

public class UserServiceImpl implements UserService {

    /**
     * 用户登入
     * @param name
     * @param pwd
     * @return
     */
    @Override
    public User login(String name, String pwd) {
        //创建DAO对象
        UserDao userDao = new UserDaoMySQLImpl();
        User user = userDao.getUserByNameAndPwd(name, pwd);
        return user;
    }


    /**
     * 显示指定用户的好物列表
     * @param user
     */
    @Override
    public void listUserGoods(User user) {
        int curPage = 0;
        //创建DAO对象
        GoodsDao goodsDao = new GoodsDaoMySQLImpl();
        Scanner input = new Scanner(System.in);
        boolean isShowGoods = true;
        List<GoodsDetail> listGoods = null;
        do {
            if (isShowGoods) {
                listGoods = goodsDao.listOnSellGoodsByUserID(user.getUserID(), curPage);
                showMyGoods(listGoods, curPage);
            }
            int pageCounts = (int) Math.ceil(goodsDao.getOnSellGoodsCountByUserID(user.getUserID()) / 5.0);
            //判断当前页是否为最后一页
            boolean hasLastPage = pageCounts > curPage + 1;
            System.out.println("1.上一页\t2.下一页\t0.返回上一级");
            System.out.print("请输入要执行的操作:");
            String action = input.next();
            if (action.equals("1")) {
                //当前页不是首页的情况
                isShowGoods = curPage > 0;
                if (isShowGoods) {
                    curPage--;
                } else {
                    System.out.println("已到首页,无法向前翻页!");
                }
                //显示下一页
            } else if (action.equals("2")) {
                //当前不是尾页的情况
                isShowGoods = hasLastPage;
                if (hasLastPage) {
                    curPage++;
                } else {
                    System.out.println("已到尾页,无法向后翻页!");
                }
            } else if (action.equals("0")) {
                break;
            } else {
                System.out.println("输入错误,请重新输入");
            }
        } while (true);
    }

    /**
     * 上架新的好物
     * @param user
     */
    @Override
    public void addNewGoods(User user) {
        try {
            Scanner input = new Scanner(System.in);
            Goods goods = new Goods();
            System.out.println("请输入好物名称:");
            goods.setName(input.next());
            //创建DAO对象
            TypeDao typeDao = new TypeDaoMySQLImpl();
            List<Type> types = typeDao.getTypeList();
            //构造好物类型提示
            String typeHint = "";
            for (int i = 0; i < types.size(); i++) {
                typeHint += i + 1 + "." + types.get(i).getName();
                if (i != types.size() - 1) {
                    typeHint += ",";
                }
            }
            System.out.println("请输入好物类别(" + typeHint + "):");
            goods.setTypeID(types.get(Integer.valueOf(input.next())).getId());
            System.out.println("请输入好物价格:");
            goods.setPrice(Float.valueOf(input.next()));
            System.out.println("请输入好物介绍:");

            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            try {
                //使用readLine()方法读取整行输入
                goods.setDescription(reader.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
            //获取系统时间
            LocalDateTime today = LocalDateTime.now();
            //将日期格式化为字符串
            goods.setAddTime(Date.from(today.atZone(TimeZone.getTimeZone("GMT+8").toZoneId()).toInstant()));
            goods.setOnSell(true);
            goods.setOwnerID(user.getUserID());
            //创建DAO对象
            GoodsDao goodsDao = new GoodsDaoMySQLImpl();
            if (goodsDao.addNewGoods(goods) > 0) {
                System.out.println("好物上架成功!");
            } else {
                System.out.println("好物上架失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("输入错误");
        }
    }

    /**
     * 显示好物信息
     * @param user
     * @param type
     */
    @Override
    public void listGoods(User user, int type) {
        int curPage = 0;
        //创建DAO对象
        GoodsDao goodsDao = new GoodsDaoMySQLImpl();
        Scanner input = new Scanner(System.in);
        boolean isShowGoods = true;
        List<GoodsDetail> listGoods = null;
        do {
            if (isShowGoods) {
                listGoods = goodsDao.listOnSellGoods(curPage, type);
                showListGoods(listGoods, curPage);
            }
            int pageCounts = (int) Math.ceil(goodsDao.getOnSellGoodsCountByType(type) / 5.0);
            //判断当前页面是否为最后一页
            boolean hasLastPage = pageCounts > curPage + 1;
            System.out.println("1.查看好物详情\t2.上一页\t3.下一页\t0.返回上一级");
            System.out.print("请输入要执行的操作:");
            String action = input.next();
            //查看
            if (action.equals("1")) {
                System.out.print("请输入要查看的好物编号:");
                int index = Integer.valueOf(input.next()) - curPage * 5;
                if (index <= listGoods.size() && index >= 1) {
                    GoodsDetail goods = listGoods.get(index - 1);
                    showGoodsDetail(goods);
                    System.out.println("1.购买此好物\t其他输入返回上一级");
                    System.out.print("请输入要执行的操作:");
                    action = input.next();
                    if (action.equals("1")) {
                        if (buyGoods(user, goods)) {
                            System.out.println("购买成功!");
                        } else {
                            System.out.println("购买失败!");
                        }
                    }
                    break;
                } else {
                    System.out.println("好物编号输入错误!");
                }
                //显示上一页
            } else if (action.equals("2")) {
                //当前不是首页的情况
                isShowGoods = curPage > 0;
                if (isShowGoods) {
                    curPage--;
                } else {
                    System.out.println("已到首页,无法向前翻页!");
                }
                //显示下一页
            } else if (action.equals("3")) {
                //当前不是尾页的情况
                isShowGoods = hasLastPage;
                if (hasLastPage) {
                    curPage++;
                } else {
                    System.out.println("已到尾页,无法向后翻页!");
                }
            } else if (action.equals("0")) {
                break;
            } else {
                System.out.println("输入错误,请重新输入");
            }
        } while (true);

    }

    /**
     * 购买好物
     * @param buyer
     * @param goods
     * @return
     */
    @Override
    public boolean buyGoods(User buyer, GoodsDetail goods) {
        //判断购买者的余额会否足够买好物
        if (buyer.getBalance() < goods.getPrice()) {
            System.out.println("余额不足,无法购买!");
        } else if (buyer.getUserID() == goods.getOwnerID()) {
            System.out.println("不能购买自己的好物!");
        } else {
            System.out.print("请输入收货信息:");
            //会使用到空格等字符,需要使用BufferedReader读取输入
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            try {
                //使用readLine()方法读取整行输入
                Tradelog tradelog = new Tradelog();
                tradelog.setReceiveInfo(reader.readLine());
                tradelog.setBuyerID(buyer.getUserID());
                tradelog.setSellerID(goods.getOwnerID());
                tradelog.setGoodsID(goods.getId());
                //获取系统时间作为交易时间
                LocalDateTime todat = LocalDateTime.now();
                //获得格式化后的日期+时间字符串
                tradelog.setTradeTime(Date.from(todat.atZone(ZoneId.systemDefault()).toInstant()));
                //创建DAO对象
                TradelogDao tradelogDao = new TradelogDaoMySQLImpl();
                GoodsDao goodsDao = new GoodsDaoMySQLImpl();
                UserDao userDao = new UserDaoMySQLImpl();
                if (tradelogDao.addTradelog(tradelog) > 0
                        && goodsDao.updateGoodsOnSellState(goods.getId(), false) > 0
                        && userDao.addBalance(goods.getOwnerID(), goods.getPrice()) > 0
                        && userDao.minusBalance(buyer.getUserID(), goods.getPrice()) > 0) {
                    return true;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private void showListGoods(List<GoodsDetail> listGoods, int curPage) {
        System.out.println("编号\t名称\t价格\t上架时间");
        for (int i = 0; i < listGoods.size(); i++) {
            GoodsDetail goods = listGoods.get(i);
            int index = curPage * 5 + i + 1;
            System.out.println(index + "\t" +
                    goods.getName() + "\t" +
                    goods.getPrice() + "\t" +
                    goods.getAddTime() + "\t");
        }
    }

    private void showGoodsDetail(GoodsDetail goods) {
        System.out.println("好物名称:" + goods.getName());
        System.out.println("好物类型:" + goods.getType());
        System.out.println("好物价格:" + goods.getPrice());
        System.out.println("好物主人:" + goods.getOwner());
        System.out.println("好物介绍:" + goods.getDescription());
        System.out.println("上架时间:" + goods.getAddTime());

    }

    private void showMyGoods(List<GoodsDetail> listGoods, int curPage) {
        System.out.println("序号\t名称\t类型\t价格\t上架时间\t描述");
        for (int i = 0; i < listGoods.size(); i++) {
            GoodsDetail goods = listGoods.get(i);
            int index = curPage * 5 + i + 1;
            System.out.println(index + "\t" +
                    goods.getName() + "\t" +
                    goods.getType() + "\t" +
                    goods.getPrice() + "\t" +
                    goods.getAddTime() + "\t" +
                    goods.getDescription());
        }
    }
}

接口

public interface AdminService {
    public Admin login(String name, String pwd);
    public void listTradeLog();
    public void listGoods(int type);
}

/**/

public interface UserService {
    public User login(String name, String pwd);
    public void listUserGoods(User user);
    public void addNewGoods(User user);
    public void  listGoods(User user, int type);
    public boolean buyGoods(User buyer, GoodsDetail goods);

}

序列化

import vo.TradelogDetail;

import java.io.ObjectStreamClass;

/**
 * 序列化
 */
public class Serialization {
    public static void main(String[] args) {
        ObjectStreamClass c = ObjectStreamClass.lookup(TradelogDetail.class);
        long serialID = c.getSerialVersionUID();
        System.out.println(serialID);
    }

}

前台

import entity.Admin;
import entity.User;
import service.AdminService;
import service.UserService;
import service.impl.AdminServiceImpl;
import service.impl.UserServiceImpl;

import java.lang.annotation.Target;
import java.util.Scanner;

/**
 * 用户与管理员前台
 */

public class TestClient {
    private static Admin admin;
    private static User user;

    public static void main(String[] args) {
        TestClient.startup();
    }

    /**
     * 启动登入页面
     */
    public static void startup() {
        //用户类型
        String userType = null;
        //名称
        String name = null;
        //密码
        String pwd = null;
        Scanner input = new Scanner(System.in);

        do {
            System.out.println("用户登录,请输账号类型:1.普通用户\t2.管理员");
            System.out.print("请输入账号类型:");
            userType = input.next();
            System.out.print("请输入账号:");
            name = input.next();
            System.out.print("请输入密码:");
            pwd = input.next();
        } while (!login(userType, name, pwd));
        if (admin != null) {
            showAdminMenu();
        } else {
            showUserMenu();
        }

    }

    /**
     * 普通用户和管理员用户要有不同的登录处理逻辑
     * @param userType
     * @param name
     * @param pwd
     * @return
     */
    public static boolean login(String userType, String name, String pwd) {
        boolean isLoginSucess = false;
        if (userType.equals("1")) {
            UserService userService = (UserService) new UserServiceImpl();
            user = userService.login(name, pwd);
            if (user != null) {
                isLoginSucess = true;
            }
        } else if (userType.equals("2")) {
            AdminService adminService = (AdminService) new AdminServiceImpl();
            admin = adminService.login(name, pwd);
            if (admin != null) {
                isLoginSucess = true;
            }
        }
        if (isLoginSucess) {
            System.out.println("登入成功");
        } else {
            System.out.println("用户名或密码错误,登入失败!");
        }
        return isLoginSucess;
    }


    /**
     * 显示管理员操作主界面
     */
    public static void showAdminMenu() {
        AdminService adminService = (AdminService) new AdminServiceImpl();
        while (true) {
            Scanner input = new Scanner(System.in);
            System.out.println("1.查看交易记录\n" +
                    "2.生成交易报告\n" +
                    "3.查看好物列表\n" +
                    "4.下架不合格商品\n" +
                    "5.封禁违规账号\n" +
                    "0.退出系统");
            System.out.print("请输入要执行的操作:");
            String action = input.next();
            if (action.equals("1")) {
                adminService.listTradeLog();
            } else if (action.equals("3")) {
                adminService.listGoods(-1);
            } else if (action.equals("0")) {
                break;
            } else if (action.equals("2") || action.equals("4") || action.equals("5")) {
                System.out.println("功能开发中...");
            } else {
                System.out.println("输入的操作编号错误!");
            }
        }
        System.out.println("再见");
    }

    /**
     * 显示普通用户的操作主界面
     */
    public static void showUserMenu() {
        Scanner input = new Scanner(System.in);
        System.out.println("-----------您的基本信息------------");
        System.out.println("用户名:" + user.getName());
        System.out.println("账户余额:" + user.getBalance());
        UserService userService = (UserService) new UserServiceImpl();
        while (true) {
            System.out.println("1.查看好物列表\n" +
                    "2.上架新的好物\n" +
                    "3.查看我的在售好物\n" +
                    "4.账户操作\n" +
                    "0.退出系统");
            System.out.print("请输入要执行的操作:");
            String action = input.next();
            if (action.equals("1")) {
                userService.listGoods(user, -1);
            } else if (action.equals("2")) {
                userService.addNewGoods(user);
                ;
            } else if (action.equals("3")) {
                userService.listUserGoods(user);
            } else if (action.equals("4")) {
                System.out.println("功能开发中...");
            } else if (action.equals("0")) {
                break;
            } else {
                System.out.println("输入的操作编号错误!");
            }
        }
        System.out.println("再见!");
    }
}

源文件:https://www.aliyundrive.com/s/stEsnuEfRde

最后修改:2022 年 11 月 27 日
如果觉得我的文章对你有用,请随意赞赏