引言
今天,我们实现收银功能。系统显示“请输入商品条形码(6位数字字符):”,用户输入的条形码在商品表中存在,则显示“输入商品数量:”,否则,提示“您输入的商品条形码不存在,请确认后重新输入”, 条形码和数量输入完毕后在销售明细表中增加一条记录(各字段信息如下:流水号根据规则生成,条形码为用户输入,商品名称及商品单价是根据输入的条形码查找商品表获取的,收银员为当前登陆用户名,销售时间为系统当前时间yyyy-mm-dd hh:mm:ss),增加成功后显示“成功增加一笔销售数据”,显示提示“是否继续收银(y/n)”。
功能实现
我们实现了一个基本的收银系统,通过产品条形码查找商品,记录销售数据,并生成唯一的流水号。它处理了用户输入、商品验证、销售记录生成和数据库插入等操作,并确保在多线程环境下流水号的唯一性。
1、数据库相关
在sale数据库中创建商品表和收银明细表,表中参数分别对应vo数据信息包中product和sale,在这两个函数中定义变量时要参数与数据库保持一致。
2、java相关
我们首先来讲一下生成流水号功能,private static Map<String, Integer> lastNumbers:一个静态 HashMap 用于存储每天的最后一个流水号序号。键是日期字符串(如 ),值是当天的最后一个流水号的编号。
private static void cashier():定义一个私有静态方法 cashier,用于处理收银操作。Scanner scan = new Scanner(System.in):创建 Scanner 对象以从控制台读取输入。
检查商品是否存在:
创建 Product 对象并设置条形码。
使用 ProductDAO.query(product) 查询商品是否存在。
如果 productList 为空,表示商品不存在,打印错误消息并退出循环。
如果商品存在,询问用户输入商品数量和收银员名字。 scan.nextLine(); 用于消耗 nextInt() 读取后留下的换行符。
从查询结果中获取找到的商品,获取商品的价格和收银员的名字。 使用 Timestamp 记录当前时间。使用 SimpleDateFormat 格式化当前日期为 yyyyMMdd 格式的字符串。
同步获取和更新今天的流水号序号:
使用 synchronized 关键字确保线程安全地访问和更新 lastNumbers。
从 lastNumbers 中获取当天的流水号并递增。
将流水号格式化为四位数字,并生成完整的流水号 (lsh)。
创建 Sale 对象,包含流水号、条形码、商品名称、价格、数量、操作员和销售时间。
将 Sale 对象插入数据库,检查插入是否成功。 根据用户输入决定是否继续收银或退出程序。 System.exit(0); 用于退出程序,input.equals("y") 和 input.equals("n") 用于判断用户输入。
结果展示
完整代码
vo—product
package vo; public class Product { private String barCode; private String productName; private float price; private String supply; public Product() { } public Product(String barCode, String productName, float price, String supply) { this.barCode = barCode; this.productName = productName; this.price = price; this.supply = supply; } public String getBarCode() { return barCode; } public void setBarCode(String barCode) { this.barCode = barCode; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public String getSupply() { return supply; } public void setSupply(String supply) { this.supply = supply; } }
vo—sale
package vo; import java.sql.Timestamp; public class Sale { private String lsh; private String barCode; private String productName; private float price; private int count; private String operator; private Timestamp saleTime; public Sale() { } public Sale(String lsh, String barCode, String productName, float price, int count, String operator, Timestamp saleTime) { this.lsh = lsh; this.barCode = barCode; this.productName = productName; this.price = price; this.count = count; this.operator = operator; this.saleTime = saleTime; } public String getLsh() { return lsh; } public void setLsh(String lsh) { this.lsh = lsh; } public String getBarCode() { return barCode; } public void setBarCode(String barCode) { this.barCode = barCode; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } public Timestamp getSaleTime() { return saleTime; } public void setSaleTime(Timestamp saleTime) { this.saleTime = saleTime; } }
dao—ProductDAO
package dao; import util.DBUtil; import vo.Product; 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 ProductDAO { public static List<Product> query(Product product) { Connection con = null; PreparedStatement pst = null; ResultSet rs = null; List<Product> productList = new ArrayList<>(); try { con = DBUtil.getConnection(); StringBuilder sql = new StringBuilder("SELECT * FROM t_shangping WHERE 1 = 1"); if (product.getBarCode() != null) { sql.append(" AND tiaoma = ?"); } pst = con.prepareStatement(sql.toString()); int paramIndex = 1; if (product.getBarCode() != null) { pst.setString(paramIndex++, product.getBarCode()); } rs = pst.executeQuery(); while (rs.next()) { Product p = new Product(); p.setBarCode(rs.getString("tiaoma")); p.setProductName(rs.getString("mingcheng")); p.setPrice(rs.getFloat("danjia")); p.setSupply(rs.getString("gongyingshang")); productList.add(p); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(con, pst); } return productList; } }
dao—SaleDAO
package dao; import util.DBUtil; import vo.Sale; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; public class SaleDAO { public static boolean insert(Sale sale) { Connection con = null; PreparedStatement pst = null; boolean success = false; try { con = DBUtil.getConnection(); String sql = "INSERT INTO t_shouyinmingxi (liushuihao,tiaoma, mingcheng, " + "danjia, shuliang, shouyinyuan, xiaoshoushijian) VALUES (?,?, ?, ?, ?, ?, ?)"; pst = con.prepareStatement(sql); pst.setString(1,sale.getLsh()); pst.setString(2, sale.getBarCode()); pst.setString(3, sale.getProductName()); pst.setFloat(4, sale.getPrice()); pst.setInt(5, sale.getCount()); pst.setString(6, sale.getOperator()); pst.setTimestamp(7, new Timestamp(sale.getSaleTime().getTime())); int rowsAffected = pst.executeUpdate(); if (rowsAffected > 0) { success = true; } } catch (SQLException e) { throw new RuntimeException(e); } finally { DBUtil.close(con, pst); } return success; } }
util—DBUtil
package util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class DBUtil { //驱动加载,只需执行一次 static{ String driveName = "com.mysql.cj.jdbc.Driver"; try { Class.forName(driveName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } //获取链接 public static Connection getConnection(){ String url = "jdbc:mysql://localhost:3306/sale?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = ""; Connection con = null; try { con = DriverManager.getConnection(url,user,password); } catch (SQLException e) { throw new RuntimeException(e); } return con; } //关闭资源 public static void close(Connection con, PreparedStatement pst){ if(con!=null) { try { con.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(pst!=null) { try { pst.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }
ui—Driver
package ui; import dao.ProductDAO; import dao.SaleDAO; import vo.Product; import vo.Sale; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.*; public class Driver { // 使用Map来存储每天的最后一个流水号序号 private static Map<String, Integer> lastNumbers = new HashMap<>(); public static void main(String[] args) { System.out.println("欢迎使用阳光超市收银系统"); cashier(); } private static void cashier() { Scanner scan = new Scanner(System.in); while (true) { System.out.println("请输入商品条形码(6位数字字符):"); String barCode = scan.nextLine(); // 检查商品是否存在 Product product = new Product(); product.setBarCode(barCode); List<Product> productList = ProductDAO.query(product); if (productList.isEmpty()) { System.out.println("您输入的商品条形码不存在,请确认后重新输入"); break; } // 商品存在,询问商品数量 System.out.println("请输入商品数量:"); int count = scan.nextInt(); scan.nextLine(); // 消耗换行符 // 收银员 System.out.println("请输入收银员:"); String name = scan.nextLine(); //scan.nextLine(); // 生成销售记录 Product foundProduct = productList.get(0); // 假设只有一个匹配的商品 float price = foundProduct.getPrice(); String operator = name; //*数据库中DateTime类型对应java中Timestamp类型 Timestamp saleTime = new Timestamp(System.currentTimeMillis()); // 获取当前时间 Date d = new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); String todayStr = df.format(d); // 同步获取和更新今天的流水号序号 synchronized (lastNumbers) { // 获取当前日期的序号,并递增 int lastNum = lastNumbers.getOrDefault(todayStr, 1); lastNum++; lastNumbers.put(todayStr, lastNum); // 格式化序号部分为四位数字 String lastNums = String.format("%04d", lastNum-1); String lsh = todayStr + lastNums; // 生成完整的流水号 Sale sale = new Sale(lsh, foundProduct.getBarCode(), foundProduct.getProductName(), price, count, operator, saleTime); // 插入销售记录 if (SaleDAO.insert(sale)) { System.out.println("成功增加一笔销售数据"); } else { System.out.println("销售数据插入失败"); } System.out.println("是否继续收银(y/n:)"); String input = scan.nextLine(); if (input.equals("y")) { } else if (input.equals("n")) { System.out.println("成功退出收银程序"); System.exit(0); } else { System.out.println("错误"); } } } } }
mysql—workbench
CREATE DATABASE sale; USE sale; DROP TABLE IF EXISTS `t_shangping`; CREATE TABLE `t_shangping` ( `tiaoma` varchar(255) NOT NULL, `mingcheng` varchar(255) DEFAULT NULL, `danjia` decimal(10,2) DEFAULT NULL, `gongyingshang` varchar(255) DEFAULT NULL, PRIMARY KEY (`tiaoma`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; select * from t_shangping; INSERT INTO `t_shangping` VALUES ('', '手机', '4500.00', '华为'); INSERT INTO `t_shangping` VALUES ('', '鼠标', '61.00', '华为'); INSERT INTO `t_shangping` VALUES ('', '矿泉水', '2.50', '农夫山泉'); INSERT INTO `t_shangping` VALUES ('', '香烟', '20.00', '武汉卷烟厂'); INSERT INTO `t_shangping` VALUES ('', '牙膏', '4.50', '中华牙膏厂'); INSERT INTO `t_shangping` VALUES ('', '电脑', '4300.00', 'dell'); INSERT INTO `t_shangping` VALUES ('', '小明同学', '5.50', '武汉饮料集团'); DROP TABLE IF EXISTS `t_shouyinmingxi`; CREATE TABLE `t_shouyinmingxi` ( `liushuihao` varchar(255) NOT NULL, `tiaoma` varchar(255) DEFAULT NULL, `mingcheng` varchar(255) DEFAULT NULL, `danjia` decimal(10,0) DEFAULT NULL, `shuliang` int DEFAULT NULL, `shouyinyuan` varchar(255) DEFAULT NULL, `xiaoshoushijian` datetime DEFAULT NULL, PRIMARY KEY (`liushuihao`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; select * from t_shouyinmingxi;
其他
其他超市系统用户功能详见:
Java超市收银系统(一、用户登录)_收银系统开发教程-CSDN博客
Java超市收银系统(二、用户权限)-CSDN博客
Java超市收银系统(三、密码修改)-CSDN博客
今天的文章 Java超市收银系统(四、收银功能)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/98843.html