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

前言:

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

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

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

一:需求分析

1:系统需实现的功能

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

2:系统模块结构

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

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内信息较为丰富,包括并不限于如下图所示信息:
基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计)_第2张图片

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类图:
基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计)_第3张图片
SearhFrame.java类图:
基于Swing与MySQL之货物仓库管理系统(可为Java大作业、甚至毕业设计)_第4张图片

四:工程结构

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

五:业务层分析

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

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:登陆

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

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

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

3:登陆失败

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

4:将货物信息入仓

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

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

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

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

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

7:根据id将货物出仓

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

七:总结

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

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

你可能感兴趣的:(Swing,数据库,java,mysql,eclipse)