本文最后更新于:1 年前
商品管理系统实战
1.题目要求
模拟实现以下商品管理业务系统,商品管理系统的整体功能有:
注:商品数据存储在一个数据库中(用静态HashMap来模拟),MySQL
- 用户可以通过输入商品信息来向库中添加商品,如:
- id,name,price,库存数量 -> p01,透明胶带,8.8,1000
- 用户可以查看数据库中所有的商品
- 用户可以通过输入一个id来查看一个商品
- 用户可以通过输入一个name来查看一个商品
- 用户可以通过输入一个价格范围(比如:100->200)来查看符合条件的商品
- 用户可以通过输入一个id来从数据库中删除一个商品
- 用户可以通过指定一个id来修改一个商品的名称
- 用户可以通过制定一个id来修改一个商品的价格
- 用户可以通过制定一个id来修改一个商品的库存数量
要求:
- 整个程序要分成:交互层、 业务逻辑(service)层、 数据访问(dao)层
- 交互层和service层之间要用“面向接口编程”的模式来写
- 业务逻辑层和dao层之间要用“面向接口编程”的模式来写
2.前期准备
- 该项目基本融合了java学习的大部分知识,我们需要熟悉前面所学的基础知识,尤其是关于类的封装、继承、多态,还有接口的使用,以及对未知错误的异常处理等方面知识;底层DAO需要掌握JDBC指令同mysql数据库处理,在交互层需要了解常用的GUI组件和设计思路框架,在此过程中需要学习相关知识,下面推荐了一些学习资料和视频。
3.设计思路
1.DAO层
DAO层主要完成对底层数据库的连接,与数据库进行数据交互,作为后面业务服务层的基础,java实现数据库的连接需要用到JDBC包(jar),使用包中相应的类方法完成数据库连接,下面展示了DAO层的实现代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package DAO;
import java.sql.*;
public class DAO implements DAOApi{ protected static Statement statement; protected static Connection connection;
public void connect() { try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/goodsmag", "root","123456"); if(connection != null) { System.out.println("连接成功"+connection); } assert connection != null; statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { System.exit(0); throw new RuntimeException(e); } } }
|
2.业务(Service)逻辑层
本层主要是实现对数据库的数据处理的各种功能,包括对数据库中表的数据的增删改查,以及各种基础功能和附加功能,本层采用接口的方法实现,通过JDBC的各种命令对数据库中数据表的数据进行各种操作,以下介绍各个功能的实现。
2.1 各功能接口
各种功能的接口提前定义好,以便于在后面的服务层中实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package Service;
import java.sql.SQLException;
public interface ServiceApi extends SearchApi, AlterApi, JudgeApi{ } interface SearchApi { Object[][] alllook() throws SQLException; Object[][] idlook(int id) throws SQLException; Object[][] namelook(String name) throws SQLException; Object[][] pricelook(float a, float b) throws SQLException; }
interface AlterApi{ void iddel(int id) throws SQLException; void alldel() throws SQLException; void add(String namevalue,String pricevalue,String numvalue) throws SQLException; void rename(int id, String newname) throws SQLException; void reprice(int id, float newprice) throws SQLException; void renumber(int id, int newnumber) throws SQLException; }
interface JudgeApi { boolean idexist(int id) throws SQLException; boolean nameexist(String name) throws SQLException; }
|
2.2 添加商品
该方法采用**Vector**来临时存储输入的需要添加的商品的各种信息,然后通过JDBC命令将其添加到数据库中,从而实现对商品的添加功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public void add(String namevalue,String pricevalue,String numvalue) { String key = "insert into goods (name, price, num) values "; int i = 1; while (i<4) { switch(i++) { case 1: { goods.put("name", namevalue); break; } case 2: { goods.put("price", pricevalue); break; } case 3: { goods.put("num", numvalue); break; } } } i = 1; v.add(goods); try{ statement.executeUpdate(key+"( \""+goods.get("name")+"\","+goods.get("price")+","+goods.get("num")+")"); } catch (SQLException e) { e.printStackTrace(); } }
|
2.3 查询所有商品
本方法通过使用一个Object数组来临时存储从数据库中查询到的所有商品数据,并将其循环添加到数组中保存,待需要时使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public Object[][] alllook() throws SQLException { String retnumsql = "SET @rownum = 0"; String reranksql = "UPDATE goods SET id = @rownum := @rownum +1"; statement.execute(retnumsql); statement.execute(reranksql); String sql1 = "select count(*) totalCount from goods"; ResultSet rs = statement.executeQuery(sql1); rs.next(); int i = 0; int count = rs.getInt("totalCount"); Object[][] rowdata = new Object[count][4]; String sql2 = "select * from goods"; ResultSet resultSet = statement.executeQuery(sql2); while(resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); float price = resultSet.getFloat("price"); int num = resultSet.getInt("num"); rowdata[i++] = new Object[]{id, name, price, num}; } return rowdata; }
|
2.4 ID查询商品
通过查询指定键的键值即ID来从数据库中查询该ID的商品,实现原理与全查询类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public Object[][] idlook (int id) throws SQLException { Object[][] rowdata = new Object[1][4]; if(idexist(id)) { ResultSet resultSet = statement.executeQuery("select * from goods where id = " + id); if(resultSet.next()){ int ID = resultSet.getInt("id"); String name = resultSet.getString("name"); float price = resultSet.getFloat("price"); int num = resultSet.getInt("num"); rowdata[0] = new Object[]{ID, name, price, num}; } } return rowdata; }
|
2.5 名字查询商品
通过传递输入的商品名字到服务层到数据库中查询指定名字的商品,原理与上文类似。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public Object[][] namelook(String name) throws SQLException { Object[][] rowdata = new Object[1][4]; if(nameexist(name)) { String sql = "select * from goods where name = \"" + name + "\""; ResultSet resultSet = statement.executeQuery(sql); if(resultSet.next()){ int ID = resultSet.getInt("id"); String Name = resultSet.getString("name"); float price = resultSet.getFloat("price"); int num = resultSet.getInt("num"); rowdata[0] = new Object[]{ID, Name, price, num}; } } return rowdata; }
|
2.6 ID删除商品
通过传递商品ID通过JDBC指令直接删除数据库中指定ID的商品。
1 2 3 4 5 6 7 8 9
| public void iddel(int id) throws SQLException { if (idexist(id)) { statement.executeUpdate("delete from goods where id=" + id); System.out.println("ID = " + id + " 的商品信息删除成功"); } else System.out.println("您的输入ID有误请查证后重新删除"); }
|
2.7 价格筛选
通过传递maxprice和minprice两个浮点数调用JDBC指令到数据库中查询处于该范围内的商品并返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public Object[][] pricelook(float a, float b) throws SQLException { String sql1 = "select count(*) totalCount from goods where price>=" + a + "and price<=" + b + "order by price"; ResultSet rs = statement.executeQuery(sql1); rs.next(); int i = 0; int count = rs.getInt("totalCount"); Object[][] rowdata = new Object[count][4]; String sql2 = "select * from goods where price>=" + a + " and price<=" + b +"order by price"; ResultSet resultSet = statement.executeQuery(sql2); while(resultSet.next()) { int id = resultSet.getInt("id"); String name = resultSet.getString("name"); float price = resultSet.getFloat("price"); int num = resultSet.getInt("num"); rowdata[i++] = new Object[]{id, name, price, num}; } return rowdata; }
|
2.8 修改数据(重命名、修改价格、修改数量)
通过传递对应的Name、Price和Number利用JDBC指令修改为输入的数据,三种修改方式实现代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public void rename(int id, String newname) throws SQLException{ if(idexist(id)) { String sql = "update goods set name=\"" + newname + "\" where id=" + id; statement.executeUpdate(sql); System.out.println("商品名修改成功"); } } public void reprice(int id, float newprice) throws SQLException{ if(idexist(id)) { String sql = "update goods set price=" + newprice + " where id=" + id; statement.executeUpdate(sql); System.out.println("商品价格修改成功"); } } public void renumber(int id, int newnumber) throws SQLException{ if(idexist(id)) { String sql = "update goods set num=" + newnumber + " where id=" + id; statement.executeUpdate(sql); System.out.println("商品数量修改成功"); } }
|
3.GUI交互层
该层主要采用Swing类的各种组件和方法实现自己想要的图形用户界面,实现过程简要分为一下几个步骤。
- 创建JFrame组件作为面板组件的载体。
- 创建JPanel组件作为基础组件的载体,并且设置面板的大小,位置以及布局方式。
- 创建JLabel、JTextField、JButton、JPassword等基本组件并且设置其格式,包括颜色、大小、位置等。
- 将创建的基本组件添加到面板中,为组件添加监视器来实现动态响应,然后设置JFrame的内容为面板,设置其居中可见即可。
下面只展示部分代码作为示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private static void showmanual(Frame owner){ final JDialog dialog = new JDialog(owner, "教程", false); dialog.setSize(800, 600); dialog.setResizable(false); dialog.setLocationRelativeTo(GuiInteractApi.jf); JLabel background = new JLabel(new ImageIcon("resources/img/教程视频.gif")); JPanel panel = new JPanel(); panel.add(background); dialog.setContentPane(panel); dialog.setVisible(true); }
|
4.结果展示
5.资源下载
程序下载链接:**项目资源包**
本程序使用的为私人云端数据库,可以直接运行程序,不需要切换为自己本地的数据库,不过也实现了软件内切换登录本地数据库,具体请自行测试.
项目创作不易,精心打磨耗时较久,从底层代码设计编写到GUI的Logo图标均为自己设计,但是仍然还有很多做的不够好的地方,请大家加以指正,有兴趣的小伙伴可以相互交流合作.
该资源包中包含了一个完整的可执行程序可以供大家学习使用,有需要的小伙伴可以联系我获取项目源代码.