引言
今天,我们实现收银功能。系统显示“请输入商品条形码(6位数字字符):”,用户输入的条形码在商品表中存在,则显示“输入商品数量:”,否则,提示“您输入的商品条形码不存在,请确认后重新输入”, 条形码和数量输入完毕后在销售明细表中增加一条记录(各字段信息如下:流水号根据规则生成,条形码为用户输入,商品名称及商品单价是根据输入的条形码查找商品表获取的,收银员为当前登陆用户名,销售时间为系统当前时间yyyy-mm-dd hh:mm:ss),增加成功后显示“成功增加一笔销售数据”,显示提示“是否继续收银(y/n)”。
功能实现
我们实现了一个基本的收银系统,通过产品条形码查找商品,记录销售数据,并生成唯一的流水号。它处理了用户输入、商品验证、销售记录生成和数据库插入等操作,并确保在多线程环境下流水号的唯一性。
1、数据库相关
在sale数据库中创建商品表和收银明细表,表中参数分别对应vo数据信息包中product和sale,在这两个函数中定义变量时要参数与数据库保持一致。
2、java相关
我们首先来讲一下生成流水号功能,private static Map<String, Integer> lastNumbers:一个静态 HashMap 用于存储每天的最后一个流水号序号。键是日期字符串(如 20240811),值是当天的最后一个流水号的编号。
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 = "123456";
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 ('100001', '手机', '4500.00', '华为');
INSERT INTO `t_shangping` VALUES ('100002', '鼠标', '61.00', '华为');
INSERT INTO `t_shangping` VALUES ('100003', '矿泉水', '2.50', '农夫山泉');
INSERT INTO `t_shangping` VALUES ('100004', '香烟', '20.00', '武汉卷烟厂');
INSERT INTO `t_shangping` VALUES ('100005', '牙膏', '4.50', '中华牙膏厂');
INSERT INTO `t_shangping` VALUES ('200001', '电脑', '4300.00', 'dell');
INSERT INTO `t_shangping` VALUES ('200002', '小明同学', '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,String,java,超市,收银,sql,import,public,pst From: https://blog.csdn.net/m0_74325713/article/details/141069926