商品管理系统(控制台程序)
简言
本项目是此次系列项目的第一篇,目的在于练习基础的sql连接及项目内容的搭建,逐步达到构建商品管理系统网络应用。
这篇文章承接上一篇文章JAVA练习系列(二):控制台程序(上),进一步对项目的dao层与view层说明。
项目代码:https://pan.baidu.com/s/1_wMqANsB2lzfoQGF3nZrwA 提取码: umwi
1. 数据库操作
需要完成以下数据库操作
GoodsDao类
需要完成对于商品的增加与删除,更改商品信息以及查询单个商品信息和查询整体商品信息。
- 增加操作
构建数据库的connection
,预编译INSERT
语句,通过传递的Goods对象获取需要插入到数据库的商品名称、商品价格及商品数量信息,由于我们在mysql数据库中设置主键gid
是AUTO INCREASEMENT
的,所以数据列会添加对应的gid编号。
public boolean addGoods(@NotNull Goods goods){
boolean result = false;
connection = DbConn.getconn();
String sql = "INSERT INTO goods(gname,gprice,gnum) VALUES(?,?,?)";
try{
pstmt = connection.prepareStatement(sql);
pstmt.setString(1, goods.getGname());
pstmt.setString(2, ""+goods.getGprice());
pstmt.setString(3, ""+goods.getGnum());
int rs = pstmt.executeUpdate();
if(rs>0){
result = true;
}
}catch(SQLException e){
e.printStackTrace();
}finally {
DbClose.addClose(pstmt, connection);
}
return result;
}
- 删除操作
与增加操作类似,通过编写删除delete语句提交事件完成数据库操作,这里需要注意根据主键信息删除对应的商品信息。
public boolean deleteGoods(int gid){
boolean result = false;
connection = DbConn.getconn();
String sql = "DELETE FROM goods WHERE gid=?";
try{
pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, gid);
int rs = pstmt.executeUpdate();
if(rs > 0){
result = true;
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DbClose.addClose(pstmt, connection);
}
return result;
}
- 更改操作
需要更改商品姓名、商品价格和商品数目。
这里需要编写不同的sql语句,通过switch
语句对不同case进行处理。
public boolean updateGoods(int key, @NotNull Goods goods){
boolean result = false;
connection = DbConn.getconn();
String sql = "UPDATE goods SET ";
try{
switch (key){
case 1:
{
String sql_name = sql + "gname = ? WHERE gid = ?";
pstmt = connection.prepareStatement(sql_name);
pstmt.setString(1, goods.getGname());
pstmt.setString(2, ""+goods.getGid());
int rs = pstmt.executeUpdate();
if(rs > 0){
result = true;
}
break;
}
case 2:
{
String sql_price = sql + "gprice = ? WHERE gid = ?";
pstmt = connection.prepareStatement(sql_price);
pstmt.setString(1, ""+goods.getGprice());
pstmt.setString(2, ""+goods.getGid());
int rs = pstmt.executeUpdate();
if(rs > 0){
result = true;
}
break;
}
case 3:
{
String sql_num = sql + "gnum = ? WHERE gid = ?";
pstmt = connection.prepareStatement(sql_num);
pstmt.setString(1, ""+goods.getGnum());
pstmt.setString(2, ""+goods.getGid());
int rs = pstmt.executeUpdate();
if(rs > 0){
result = true;
}
break;
}
default:
break;
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DbClose.addClose(pstmt, connection);
}
return result;
}
- 查询操作
通过sql语句以及对象的查询变量和查询顺序完成定制。
将所有获取的数据通过新建相应对象实现实例化对象后添加到列表中。
public ArrayList<Goods> queryGoods(int key){
ArrayList<Goods> goodsList = new ArrayList<Goods>();
connection = DbConn.getconn();
String sql = "SELECT * FROM goods ";
try{
switch (key){
case 1:{
//根据商品数量升序排列
String sql_goods = sql + "ORDER BY gnum ASC";
pstmt = connection.prepareStatement(sql_goods);
rs = pstmt.executeQuery();
while(rs.next()){
goodsList.add(getGoodsResult(rs));
}
break;
}
case 2:{
String sql_price = sql + "ORDER BY gprice ASC";
pstmt = connection.prepareStatement(sql_price);
rs = pstmt.executeQuery();
while(rs.next()){
goodsList.add(getGoodsResult(rs));
}
break;
}
case 3:{
String name = ScannerChoice.ScannerInfoString();
String sql_name = sql + "WHERE gname LIKE '%'||?||'%'";
pstmt = connection.prepareStatement(sql_name);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
while(rs.next()){
goodsList.add(getGoodsResult(rs));
}
break;
}
default:
break;
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DbClose.queryClose(pstmt, rs, connection);
}
return goodsList;
}
SalesManDao类
对于销售员的增删改查操作与GoodsDao类基本相同,这里便不在重述。另外需要实现销售员系统登录对应的销售员,因此需要从数据库中通过输入的售货员的姓名
获取到对应销售员的账号密码
,重新生成售货员对象。
public ArrayList<Salemans> checkstandLog(String sName){
ArrayList<Salemans> salemansInfo = new ArrayList<>();
connection = DbConn.getconn();
String sql = "SELECT sid, spassword FROM salelman WHERE sname = ?";
try{
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, sName);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
int sid = resultSet.getInt("sid");
String spassword = resultSet.getString(2);
Salemans salemans = new Salemans(sid, spassword);
salemansInfo.add(salemans);
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DbClose.addClose(preparedStatement, connection);
}
return salemansInfo;
}
GsalesDao类
这里需要完成每日的交易活动
需要获取到商品的基本信息,商品名称、价格、数量以及总的销售情况。
public ArrayList<Gsale> dailyGsales(){
ArrayList<Gsale> gsalesList = new ArrayList<>();
connection = DbConn.getconn();
String sql = "SELECT gname, gprice, gnum, allSum FROM goods, (SELECT gid as salesid, sum(snum) as allSum FROM gsales WHERE trunc(sdate) = trunc(sysdate) group by gid) WHERE gid = salesid";
try{
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
gsalesList.add(getGsaleResult(resultSet));
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DbClose.queryClose(preparedStatement, resultSet, connection);
}
return gsalesList;
}
我们对于数据库的操作基本就是这些,接下来我们需要通过客户端去调用这些方法来实现我们的交易活动。
2. 工具类编写
在编写客户端界面之前,由于项目在计算过程中需要涉及到浮点数的运算,因此我们需要对浮点数的精度进行确定;同时,因为是控制台程序,我们的输入输出都是在客户端进行,需要把客户端的输入进行封装。
Arith
类
提供运算过程中的精度计算,包含加法、减法、乘法和除法,对BigDecimal
类型数据进行四舍五入操作。
需要注意的是对输入数据的处理,先转化为字符串避免因精度直接舍去数据
。
import java.math.BigDecimal;
public class Arith {
// 默认除法精度
private static final int DefDivScale = 2;
private Arith() {
}
/**
* 提供加法运算
* @param tempAddNumber1
* @param tempAddNumber2
* */
public static double add(double tempAddNumber1, double tempAddNumber2) {
//转为字符串避免丢失数据
BigDecimal num1 = new BigDecimal(Double.toString(tempAddNumber1));
BigDecimal num2 = new BigDecimal(Double.toString(tempAddNumber2));
return num1.add(num2).doubleValue();
}
/**
* 提供减法运算
* @param tempSubNumber1
* @param tempSubNumber2
* */
public static double sub(double tempSubNumber1, double tempSubNumber2) {
BigDecimal num1 = new BigDecimal(Double.toString(tempSubNumber1));
BigDecimal num2 = new BigDecimal(Double.toString(tempSubNumber2));
return num1.subtract(num2).doubleValue();
}
/**
* 提供乘法运算
* @param tempMulNumber1
* @param tempMulNumber2
* **/
public static double mul(double tempMulNumber1, double tempMulNumber2) {
BigDecimal num1 = new BigDecimal(Double.toString(tempMulNumber1));
BigDecimal num2 = new BigDecimal(Double.toString(tempMulNumber2));
return num1.multiply(num2).doubleValue();
}
/**
* 提供相对精度的除法运算。当除不尽时,由scale参数指定精度,以后的数字四舍五入
* @param tempDivNumber1
* @param tempDivNumber2
* @return double 参数之商
* */
public static double div(double tempDivNumber1, double tempDivNumber2) {
return div(tempDivNumber1, tempDivNumber2, DefDivScale);
}
private static double div(double tempDivNumber1, double tempDivNumber2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal num1 = new BigDecimal(Double.toString(tempDivNumber1));
BigDecimal num2 = new BigDecimal(Double.toString(tempDivNumber2));
//BigDecimal.ROUND_HALF_UP 向"最接近的"数字舍入, 如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
return num1.divide(num2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位数四舍五入处理
* @param tempRoundNumber 需要处理数字
* @param scale 精度
* @return double结果
* */
public static double round(double tempRoundNumber, int scale){
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal num = new BigDecimal(Double.toString(tempRoundNumber));
// BigDecimal one = new BigDecimal("1");
// return num.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
return num.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
ScannerChoice
类
需要实现控制台输入,获取相应的Double
类型、Int
类型和String
类型
通过Scanner类获取控制台输入的字符。
public static double ScannerDouble(){
double num ;
do{
Scanner scanner = new Scanner(System.in);
System.out.println("请输入两位小数:\n");
String info = scanner.next();
String regex = "(([1-9][0-9]*)\\.([0-9]{2}))|[0]\\.([0-9]{2})";//保留小数点后2位小数
if(info.matches(regex)){
num = Double.parseDouble(info);
}
else{
System.out.println("输入有误!");
continue;
}
break;
}while(true);
return num;
}
/**
* 输入商品数量
* **/
public static int ScannerNum(){
int num ;
do{
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
String nums = scanner.next();
String regex = "([1-9])|([1-9][0-9]+)";
if(nums.matches(regex)){
num = Integer.parseInt(nums);
}else{
System.out.println("输入有误");
continue;
}
break;
}while(true);
return num;
}
/**
* 操作界面输入
* 0 退出界面
* **/
public static String ScannerInfoString(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
return scanner.next();
}
3. 客户端程序编写
我们需要完成以下页面编写:
-
主页面
包含商品维护界面、前台收银界面和商品管理界面的入口及程序的退出。
-
商品维护界面
包含商品的操作,对商品的增加、删除,更改商品信息和查询商品信息。
-
前台收银界面
用于登录商品购买的交易活动界面
-
商店管理界面
包含商店内的售货员管理与查看当天的营业情况
那么控制台程序基本到此结束啦!
这个项目基本是简单的数据库操作,需要对数据库有一点了解,目的也是如此。
Bye!