基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计)

2023-05-16

前言:

该系统总代码行数约2100行,采用技术栈为Swing框架与MySQL,编码环境为Eclipse。实现的功能有:用户注册、登陆;货物入仓、货物出仓,货物信息更新与货物信息查询(对货物信息的增删改查)。

对于Java大作业或课程结课作业而言,须侧重分析基本语法,面向对象设计三要素(封装、继承、多态),基本泛型集合的简单使用,数据库接口的操作与工程设计规范;对于面向对象分析与设计而言,须侧重分析用例图与用例建模,类图与对象图之间的分析与设计,状态图;对于毕业设计而言,可在该系统基础上增加用户权限与角色管理,货物信息分析与打印导出,更改系统偏好设置来达到论文设计要求。

该系统主要分为controller层与service层(笔者由于开发工具原因没有单独对View分层,但不影响系统工程性),controller层绘制UI,接收数据并调用service层实例对象的具体业务方法,service层中的接口方法编写业务语句,调用dao层使其直接与数据库底层操作,并按此逆顺序将数据返回至UI。

一:需求分析

1:系统需实现的功能

  • 系统需提供注册功能与登陆功能以进入主管理界面
  • 系统需提供货物信息入仓功能
  • 系统需根据精准条件将货物信息出仓
  • 系统需根据精准条件更新货物信息
  • 系统需根据精准条件查询货物信息

2:系统模块结构

在这里插入图片描述

3:功能需求

  • 提供注册账户功能
  • 提供根据输入账户验证登陆功能
  • 提供根据输入的全部信息将货物入仓功能
  • 提供根据id将货物出仓功能
  • 提供根据货物名称将货物出仓功能
  • 提供根据销售者将货物出仓功能
  • 提供根据购买日期将货物出仓功能
  • 提供根据id更新货物名称功能
  • 提供根据id更新货物销售者功能
  • 提供根据id更新货物购买单价功能
  • 提供根据id更新货物购买数量功能
  • 提供根据id更新货物使用数量功能
  • 提供根据id更新货物销售单价功能
  • 提供根据日期查询货物信息功能
  • 提供根据销售者查询货物信息功能
  • 提供根据货物名称查询货物信息功能
  • 提供根据id查询货物信息功能

4:软件/硬件需求

  • 操作系统平台不限(OS X/ Linux/ Windows)
  • Java JDK 1.7及以上
  • MySQL 8.0及以上

二:系统设计思路

1:数据库设计

系统主要服务两个实体对象,一个为“登陆者”,另一个即为“货物”,那么可设计两个数据表:

user_login
stock_detail

user_login内应存在关于账户与密码的字段,即如下图所示:
在这里插入图片描述
stock_detail内信息较为丰富,包括并不限于如下图所示信息:
在这里插入图片描述

2:.dao设计

该层主要与数据库直接操作以得到connection来进行statement。局部代码如下:

	public ResultSet getResult(String sqlContent){
		try{
			resultSet = statement.executeQuery(sqlContent);
			return resultSet;
		} catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}

说明:该方法返回一个ResultSet对象,接收参数为要执行的SQL语句。

3:.service设计

该层主要定义接口,提供抽象方法,供.service.impl实现。局部实例代码如下:
LoginService.java:

public interface LoginService {
	public int login(String account, String password);
	public int register(String account, String password);
}

说明:第一个抽象方法接收两个参数用户验证登陆,返回类型为int类型。

4:.service.impl设计

该层主要用来实现(implements.service层提供的接口并重写其抽象方法。局部实例代码如下:
LoginService.java:

public class LoginServiceImpl implements LoginService{

	@Override
	public int login(String account, String password) {
		// TODO Auto-generated method stub
		DBUtil db = new DBUtil();
		String sql = "select * from user_login where account = '" + account + "' and password = '" + password + "';";
		ResultSet resultSet = db.getResult(sql);
		try {
			if(resultSet.next()){
				return 1;
			} else{
				return 0;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.close();
		}
		return 0;
	}

	@Override
	public int register(String account, String password) {
		// TODO Auto-generated method stub
		DBUtil db = new DBUtil();
		String sql = "INSERT INTO `stock_manager`.`user_login` (`account`, `password`) VALUES ('" + account + "', '" + password + "');";
		try{
			db.updateData(sql);
			return 1;
		} catch(Exception e){
			e.printStackTrace();
		} finally {
			db.close();
		}
		return 0;
	}

}

说明:第一个重写方法先拿到DBUtil()实例对象,后拼接一SQL语句从user_login表中检索是否存在该用户,如果结果集(ResuleSet)不为空,即存在该用户,就返回1,否则0。

5:.controller设计

该层用于绘制UI及控制逻辑。局部示例代码如下:
LoginFrame.java:

public class LoginFrame {

	private JFrame frmLogin;
	private JTextField accountTextField;
	private JPasswordField passwordField;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					LoginFrame window = new LoginFrame();
					window.frmLogin.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	public class Login implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			LoginServiceImpl loginServiceImpl = new LoginServiceImpl();
			int status = loginServiceImpl.login(accountTextField.getText().toString(), passwordField.getText().toString());
			
			if(status == 1){
				MainFrame mainFrame = new MainFrame(accountTextField.getText().toString());
				mainFrame.frmStockManager.setVisible(true);
				frmLogin.dispose();
			} else{
				JOptionPane.showMessageDialog(null, "Login Failed!");
			}
		}
		
	}
	
	public class Register implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			LoginServiceImpl loginServiceImpl = new LoginServiceImpl();
			int status = loginServiceImpl.register(accountTextField.getText().toString(), passwordField.getText().toString());
			
			if(status == 1){
				JOptionPane.showMessageDialog(null, "Register Succeed!");
			} else{
				JOptionPane.showMessageDialog(null, "Register Failed!");
			}
			
		}
		
	}

	/**
	 * Create the application.
	 */
	public LoginFrame() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		
		try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
           // java.util.logging.Logger.getLogger(RevertSql.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
           // java.util.logging.Logger.getLogger(RevertSql.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
           // java.util.logging.Logger.getLogger(RevertSql.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
           // java.util.logging.Logger.getLogger(RevertSql.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
		
		frmLogin = new JFrame();
		frmLogin.setTitle("Login");
		frmLogin.setBounds(100, 100, 514, 264);
		
		int windowWidth = frmLogin.getWidth(); 
		int windowHeight = frmLogin.getHeight(); 
		Toolkit kit = Toolkit.getDefaultToolkit(); 
		Dimension screenSize = kit.getScreenSize(); 
		int screenWidth = screenSize.width; 
		int screenHeight = screenSize.height; 
		frmLogin.setLocation(screenWidth/2-windowWidth/2, screenHeight/2-windowHeight/2);
		
		frmLogin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmLogin.getContentPane().setLayout(null);
		
		JLabel accountLabel = new JLabel("Account");
		accountLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		accountLabel.setBounds(192, 44, 54, 15);
		frmLogin.getContentPane().add(accountLabel);
		
		JLabel passowrdLabel = new JLabel("Password");
		passowrdLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		passowrdLabel.setBounds(192, 108, 65, 15);
		frmLogin.getContentPane().add(passowrdLabel);
		
		accountTextField = new JTextField();
		accountTextField.setFont(new Font("宋体", Font.PLAIN, 12));
		accountTextField.setBounds(292, 41, 165, 24);
		frmLogin.getContentPane().add(accountTextField);
		accountTextField.setColumns(10);
		
		JButton loginButton = new JButton("Login");
		loginButton.addActionListener(new Login());
		loginButton.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		loginButton.setBounds(192, 163, 93, 23);
		frmLogin.getContentPane().add(loginButton);
		
		JButton registerButton = new JButton("Register");
		registerButton.addActionListener(new Register());
		registerButton.setFont(new Font("微软雅黑", Font.PLAIN, 12));
		registerButton.setBounds(364, 163, 93, 23);
		frmLogin.getContentPane().add(registerButton);
		
		JLabel lblNewLabel_2 = new JLabel("Stock");
		lblNewLabel_2.setFont(new Font("微软雅黑 Light", Font.BOLD | Font.ITALIC, 28));
		lblNewLabel_2.setHorizontalAlignment(SwingConstants.CENTER);
		lblNewLabel_2.setForeground(Color.BLUE);
		lblNewLabel_2.setBounds(38, 44, 86, 55);
		frmLogin.getContentPane().add(lblNewLabel_2);
		
		JLabel lblManager = new JLabel("Manager");
		lblManager.setFont(new Font("微软雅黑 Light", Font.PLAIN, 29));
		lblManager.setHorizontalAlignment(SwingConstants.CENTER);
		lblManager.setForeground(new Color(0, 191, 255));
		lblManager.setBounds(10, 94, 145, 55);
		frmLogin.getContentPane().add(lblManager);
		
		passwordField = new JPasswordField();
		passwordField.setFont(new Font("宋体", Font.PLAIN, 12));
		passwordField.setBounds(292, 105, 165, 24);
		frmLogin.getContentPane().add(passwordField);
	}
}

说明:Login类实现的逻辑为:根据返回数据是1或0来判断是否登陆成功,如果成功就启动主窗口,否则就显示JOptionPane提示用户登陆失败。

6:.util设计

该层用以提供工具类。其中一个业务逻辑为:自动生成不重复自增的货物id。示例文件如下:
GenerateStockId.java:

public class GenerateStockId {
	public static long getStockId(){
		long id = 0;
		DBUtil db = new DBUtil();
		String sql = "select * from stock_detail order by stock_id desc limit 1;";
		ResultSet resultSet = db.getResult(sql);
		try {
			while(resultSet.next()){
				long getId = resultSet.getInt("stock_id");
				getId++;
				id = getId;
			}
			return id;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.close();
		}
		return id;
	}
	
}

注意:这里提供的是静态方法,直接调用即可。

三:类图

这里只展示局部文件的类图
MainFrame.java类图:
在这里插入图片描述
SearhFrame.java类图:
在这里插入图片描述

四:工程结构

在这里插入图片描述

五:业务层分析

这里以查询功能为例分析。

1:定义接口

SearchService.java:

public interface SearchService {
	public List<List<String>> queryById(String id);
	public List<List<String>> queryByName(String name);
	public List<List<String>> queryBySeller(String seller);
	public List<List<String>> queryByDate(String date);
}

说明:这里定义四个抽象方法,其作用通过名称也很容易得出。以第一个抽象方法为例,其接收参数为id,返回类型为泛型集合

2:接口实现类

SearchServiceImpl.java:

public class SearchServiceImpl implements SearchService{

	@Override
	public List<List<String>> queryById(String id) {
		// TODO Auto-generated method stub
		List<List<String>> list = new ArrayList<List<String>>();
		DBUtil db = new DBUtil();
		String sql = "select * from stock_detail where stock_id = '" + id + "';";
		ResultSet resultSet = db.getResult(sql);
		try {
			while(resultSet.next()){
				List<String> sList = new ArrayList<String>();
				sList.add(String.valueOf(resultSet.getInt("stock_id")));
				sList.add(resultSet.getString("stock_name"));
				sList.add(resultSet.getString("stock_seller"));
				sList.add(resultSet.getString("stock_purchase_amount"));
				sList.add(resultSet.getString("stock_current_amount"));
				sList.add(resultSet.getString("stock_purchase_price"));
				sList.add(resultSet.getString("stock_sell_price"));
				sList.add(resultSet.getString("stock_purchase_date"));
				sList.add(resultSet.getString("stock_used_amount"));
				list.add(sList);	
				sList = null;
			}
			return list;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			db.close();
		}
		return null;
	}
	...
}

说明:这里先定义一个泛型集合,其作用是存入从结果集里迭代取出的货物数据信息。在结果集里面,先定义一参数为String类型的泛型集合,其作用是存入货物数据信息,每次迭代完成设置其为空以便下次迭代继续。

3:如何使用

实例化SearchServiceImpl并调用其重写方法并将返回类型赋予泛型集合即可。

六:运行效果

1:登陆

在这里插入图片描述

2:登陆成功后进入主界面

在这里插入图片描述

3:登陆失败

在这里插入图片描述

4:将货物信息入仓

在这里插入图片描述
在这里插入图片描述

5:根据id将货物信息更改

在这里插入图片描述

6:根据日期查询货物信息

在这里插入图片描述

7:根据id将货物出仓

在这里插入图片描述

七:总结

  • 良好的工程结构是软件工程必须掌握的目标,其作用就是减少代码间耦合、增加内聚、提高利用率
  • 完备的软件需求分析、软件设计、数据库设计与分析是系统构建的必要条件。残缺、不充分的需求分析与设计只会带来灾难
  • 提高人机交互的效率是软件设计的一个目标。良好的人际交互界面会使软件使用臃肿度降低
  • 充分利用面向对象的三个基本要素,使其达到在软件设计、软件开发、软件测试、软件修改流程中的得力助手。

有需要的读者可以留言获取。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计) 的相关文章

随机推荐

  • 不忘初心,能偷懒就偷懒:C#操作Word文件

    换了一家公司 xff0c 新单位的信息化建设仍然在路上 OA也正在建设中 xff0c 目前项目发票报销等流程仍然是手工的 xff0c 只能线下填单子 至于是电脑上填好打印出来还是直接空白模板打出来手写倒是不管 xff0c 随意 疫情期间积压
  • Python读写JSON格式数据

    文章目录 JSON格式数据简介使用Python读写JSON格式数据1 读取json文件2 写入json文件 自己编写一个JsonUtils JSON格式数据简介 JSON文件的读写应算成Python基础知识的内容 xff0c 但是由于在编写
  • 银河麒麟初体验

    国产替代及信创看样子是个趋势了 本行业尽管暂未强制 xff0c 但是也被吹风了 xff0c 因此技术储备也要准备起来了 在此大背景及机缘巧合之下 xff0c 接触到了银河麒麟 不吹不黑 xff0c 初体验的感觉就是换壳CentOS 特别申明
  • openEuler@树莓派

    前几天跟华为的销售 售前兄弟探讨国产信创替代 xff0c 话题自然包含了open欧拉操作系统 周末突然又想起这茬儿了 xff0c 就去官网浏览了一下 本想只是随便再进一步了解下 xff0c 没想到居然看到了这个 xff1a 嗯 xff0c
  • 使用树莓派做Apache2 HA实验

    听闻树莓派也已经是个理财产品了 xff0c 默默关闭了某宝网页的我不禁陷入了沉思 xff0c 然后翻出了之前买的一堆3B 话说回来 xff0c 虽然账面上浮盈了 xff0c 但乐不出来 按郭德纲的说法 xff0c 真乐出来这堆树莓派治不好我
  • 真拿树莓派做Linux学习机靠谱不?

    反方辩友 xff1a 不靠谱 xff0c 太贵 干嘛不直接跑个虚拟机 xff1f 我很欣赏一个观点 xff1a 入门的第一奥义是不折腾 就这个方面而言 xff0c 树莓派官方OS确实做的不错 但树莓派的初心毕竟是个学习机 xff0c 跟其他
  • 灌水时间:树莓派4+Lakka做怀旧游戏机

    大力出奇迹 忘了树莓派里还插着TF卡就要想把主板从外壳里取下 xff0c 这把杯具 xff0c TF卡槽都被扯了下来 xff0c 这块理财产品瞬间就失去了投资属性 xff0c 变成了自用的 产品 好在使用价值还在 xff0c USB启动不影
  • 树莓派4:安装 .NET 6 SDK 并测试连接 MSSQL SERVER(无 mono)

    本文基于 2022 09 06 raspios bullseye arm64 首先安装操作系统 xff0c 推荐再 修改国内源 并sudo apt y update amp amp sudo apt y upgrade 如果喜欢在windo
  • 使用树莓派学习PostgreSQL

    知乎上刷到一个口水仗 xff0c 大意是mysql和postgresql哪个好 这种问题 xff0c 正如Java和C 哪个好之类的 xff0c 我一向都是当八卦浏览的 xff0c 只看不参与 xff0c 又不是豆花该吃甜还是该吃咸这种原则
  • 使用树莓派学习PostgreSQL(二):通过MSSQL Linked Server导入数据

    作为曾经呆过证券公司营业部的从业未遂人员 xff0c 兼十年老韭菜 xff0c 对我大A还是有蜜汁感情的 看着树莓派里空空荡荡的PGSQL xff0c 突发奇想 xff0c 尝试把今天的A股数据导进来 xff1f 之前写过一个基于MSSQL
  • 试图在WinPE下用cmd.exe调包sethc.exe/utilman.exe/osk.exe来重置管理员密码,但是无法调出命令行

    忘记windows密码 xff0c 最简单的办法就是使用自带账号工具的第三方winpe xff0c 直接重置密码完事儿 xff08 但如果有基于该账号加密的东西那就回不来了 xff09 xff1b 如果手头没有这样的pe盘也没关系 xff0
  • 树莓派:在VSCode中使用C#开发.Net软件(console)

    树莓派官方桌面系统支持VSCode xff0c 我们也可以在树莓派上使用C 开发 Net软件 本文作为一个笔记简单记录 1 安装VSCode xff1a 首先打开首选项中的Recommended Software xff0c 找到Progr
  • Debian DNS完整配置

    DNS服务 执行下面的命令安装 apt install y bind9 dnsutils 这些文件分别对应的作用如下 xff1a db 127 反向区域数据库 xff0c 用于将ip解析为对应的域名 db local 正向区域数据库 xff
  • 树莓派4B:跑通Paddle-Lite-Demo

    上周跟以前单位的大神见面 xff0c 期间大神聊到了百度飞桨框架 xff0c 并建议我看看能不能做点什么有意思的东西跑在树莓派上 大神就是大神 xff0c AI是我等学渣也配玩的吗 不过既然大神都这么推荐了那就尝试一下 xff0c 大不了从
  • 在NUC8上折腾安装Windows Server 2019

    整理我的吃灰物资时意外发现还有个八代的NUC迷你主机 想着现在内存和SSD都不贵 xff0c 干脆升级了然后装个Windows Server 2019玩玩 xff0c 跑个Hyper V做些实验 于是买了2根16G 2400的内存和1条1T
  • Ubuntu上跑通PaddleOCR

    书接上文 刚才说到我已经在NUC8里灌上了Windows Server 2019 接下来也顺利的启用了Hyper V角色并装好了一台Ubuntu 22 04 LTS 的虚机 由于自从上回在树莓派上跑通了Paddle Lite Demo之后想
  • 树莓派4:跑通Tensorflow的Sequential模型用于图片分类

    重要提示 xff1a 由于树莓派相对孱弱的性能 xff0c 直接在其上训练模型可能花 xff08 lang4 xff09 费非常长的时间 本文仅作为示例性的可行性参考 xff0c 请酌情考虑实验平台 著名的Tensorflow框架也可以运行
  • C# + .Net6 实现TensorFlow图片分类

    微软官网上发现一篇很有意思的文档 xff1a 教程 xff1a 用于对图像进行分类的 ML NET 分类模型 ML NET Microsoft Learn 这篇教程写的很学院派 xff0c 但有点碎 xff0c 属于上课不能打一秒钟瞌睡的那
  • 如何用一个废旧的笔记本打造一个家庭网络服务器?

    本来好好的笔记本的 xff0c 可偏偏屏幕说烂就烂 xff0c 那就干脆不要了 xff0c 改造改造吧 xff01 他本来长这样的 xff0c 如图 xff1a 什么 xff0c 你看见了水印 老哥 xff0c 别在意这些细节 简单说一下配
  • 基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计)

    前言 xff1a 该系统总代码行数约2100行 xff0c 采用技术栈为Swing框架与MySQL xff0c 编码环境为Eclipse 实现的功能有 xff1a 用户注册 登陆 xff1b 货物入仓 货物出仓 xff0c 货物信息更新与货