基于jdbc+mysql+java的简单货物管理系统

智能软件(后端+测试) 路线篇

第一阶段:

  1. java+mysql+jdbc综合实战应用+ai
  2. 企业级框架
  3. 工具:eclipse

第二阶段

  1. seevlet+ssm框架+vue+ai综合实战
  2. serclet
  3. 工具:
    • idea
    • iflycode大模型
    • git
    • maven
  4. 组内任务
    1. 项目开发
    2. 答辩

第三阶段

  1. 基于vue+springboot+ai的前后端分离模式的应用开发
  2. springboot
  3. mybatsplus

第四阶段

  1. 测试课程
    • 功能
    • 接口
    • 性能
    • 自动化
  2. 测试计划,测试报告

考核

  1. 平时成绩30%
    1. 考勤30%
    2. 作业40%
    3. 平时表现30%
  2. 项目综合成绩70%
    1. 认证考试50%
    2. 各阶段项目答辩成绩50%

货物管理系统

组名:可惜猪猪侠不会飞

组长:陈强(service层 )

组员:吴硕 (pojo层,dao层) 吴海龙(测试) 田浩(view层)

一、项目背景

为了帮老大爷进行仓库货物管理我们需要设计程序

image-20240329090115855

二、项目技术

开发环境:

  1. 操作系统:Windows 10
  2. 集成开发环境:Eclipse
  3. 数据库管理系统:MySQL 5.7
  4. JDK版本:Java SE Development Kit 8
  5. JDBC驱动:mysql-connector-java-8.0.23.jar

所用到的技术:

  1. Java:作为编程语言,用于编写后端逻辑和处理数据。
  2. JDBC(Java Database Connectivity):Java数据库连接,用于连接和操作数据库。
  3. MySQL:关系型数据库管理系统,用于存储和管理货物管理系统的数据。

以下是一个简单的示例代码,用于连接MySQL数据库并执行查询操作:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class GoodsManagementSystem {
    public static void main(String[] args) {
        try {
            // 加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 连接数据库
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/goods_management?useSSL=false&serverTimezone=UTC", "root", "your_password");
            // 创建Statement对象
            Statement statement = connection.createStatement();
            // 执行查询操作
            ResultSet resultSet = statement.executeQuery("SELECT * FROM goods");
            // 处理查询结果
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                double price = resultSet.getDouble("price");
                System.out.println("ID: " + id + ", Name: " + name + ", Price: " + price);
            }
            // 关闭资源
            resultSet.close();
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、项目需求

开发需求如下:

  1. 使用Java语言编写货物管理系统,要求使用JDBC连接MySQL数据库。
  2. 系统需要有图形用户界面
  3. 系统需要具备以下功能:
    • 增加货物信息:用户可以输入货物的名称、数量、价格等信息,点击添加按钮后,将这些信息存储到MySQL数据库中。
    • 删除货物信息:用户可以在界面上选择要删除的货物,点击删除按钮后,将该货物的信息从数据库中删除。
    • 修改货物信息:用户可以在界面上选择要修改的货物,然后修改其信息,点击保存按钮后,将修改后的信息更新到数据库中。
    • 查询货物信息:用户可以输入货物名称或其他关键字,点击查询按钮后,在界面上显示符合条件的货物信息。
  4. 系统需要实现打包成可执行的jar文件,方便在其他计算机上运行。
  5. 系统需要有良好的错误处理和提示功能,确保用户在使用过程中能够获得及时的反馈信息。

四、项目设计架构

三层架构设计如下:

  1. 数据访问层(DAO层):负责与数据库进行交互,实现对货物信息的增删改查操作。主要包括以下类和方法:

    • GoodsDao:负责连接数据库,提供增加、删除、修改和查询货物信息的方法。
    • Goods:表示货物实体类,包含货物的属性(如名称、数量、价格等)。
  2. 业务逻辑层(Service层):负责处理业务逻辑,调用DAO层的方法完成具体的业务操作。主要包括以下类和方法:

    • GoodsService:负责处理货物管理的业务逻辑,包括增加、删除、修改和查询货物信息。
  3. 表现层(View层):负责与用户交互,展示界面并提供用户操作的入口。主要包括以下类和方法:

    • MainFrame:主窗口类,用于显示系统界面,包括按钮、输入框等组件。
    • GoodsController:控制器类,用于处理用户的操作,调用Service层的方法完成相应的业务逻辑。

这样的三层架构设计可以使得代码结构清晰,便于维护和扩展。

五、项目功能的实现

数据库设计

/*
Navicat MySQL Data Transfer

Source Server         : bp
Source Server Version : 80300
Source Host           : localhost:3306
Source Database       : wtf

Target Server Type    : MYSQL
Target Server Version : 80300
File Encoding         : 65001

Date: 2024-03-29 09:03:58
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for admin
-- ----------------------------
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin` (
  `aname` varchar(255) DEFAULT NULL,
  `apassward` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of admin
-- ----------------------------
INSERT INTO `admin` VALUES ('admin', '123');

-- ----------------------------
-- Table structure for info
-- ----------------------------
DROP TABLE IF EXISTS `info`;
CREATE TABLE `info` (
  `sno` varchar(20) NOT NULL,
  `sname` varchar(40) NOT NULL,
  `sprice` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`sno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

-- ----------------------------
-- Records of info
-- ----------------------------
INSERT INTO `info` VALUES ('001', '伊利多', '2.5');
INSERT INTO `info` VALUES ('002', '巧克力', '4');
INSERT INTO `info` VALUES ('003', '奥利奥', '11');
INSERT INTO `info` VALUES ('121', '123', '12');
INSERT INTO `info` VALUES ('201', '酸奶', '30');
INSERT INTO `info` VALUES ('201402', '薯片', '30');
INSERT INTO `info` VALUES ('2411', '棒棒糖', '7');
INSERT INTO `info` VALUES ('291832', '周', '16');
INSERT INTO `info` VALUES ('请1e', '1212', '12312');

-- ----------------------------
-- Table structure for object
-- ----------------------------
DROP TABLE IF EXISTS `object`;
CREATE TABLE `object` (
  `objectid` varchar(255) DEFAULT NULL,
  `oname` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of object
-- ----------------------------

-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `uid` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of test
-- ----------------------------

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `uid` int NOT NULL AUTO_INCREMENT,
  `uname` varchar(255) DEFAULT NULL,
  `upassward` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `usex` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '17775592351', 'man');
INSERT INTO `user` VALUES ('2', 'huser', '1762638129132', 'woman');
INSERT INTO `user` VALUES ('3', 'xues', '123', 'man');


一、目录

package rjgc;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.sql.*;

/*
 * 增加对话窗口
 */
public class Adddialog extends JFrame {
	public static final int Width = 320;
	public static final int Heigth = 230;

	Button btn, btn2;
	JTextField jt, jt2, jt3;

	public Adddialog() {
		setSize(Width, Heigth);
		setLocation(820, 200);
		setResizable(false);
		setTitle(new String("增加:"));
		setLayout(new FlowLayout());
		Container con = getContentPane();
		jt = new JTextField(20);
		Label lb = new Label("商品号:");
		jt2 = new JTextField(20);
		Label lb2 = new Label("商品名称:");
		jt3 = new JTextField(20);
		Label lb3 = new Label("商品价格:");
		btn = new Button("添加");
		btn.addActionListener(new Enter());// 监控添加键
		btn2 = new Button("取消");
		btn2.addActionListener(new Quit());// 监控取消键

		add(lb);
		add(jt);
		add(lb2);
		add(jt2);
		add(lb3);
		add(jt3);
		add(btn);
		add(btn2);

	}

	class Enter implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			Container con = getContentPane();
			if (e.getActionCommand().equals("添加")) {
				con.setBackground(Color.green);
				String sno = jt.getText();
				String sname = jt2.getText();
				String sprice = jt3.getText();
				if (sno.length() == 0)
					JOptionPane.showMessageDialog(null, "添加失败,商品号不能为空!", "操作提示",
							JOptionPane.NO_OPTION);
				else if (sname.length() == 0)
					JOptionPane.showMessageDialog(null, "添加失败,商品名称不能为空!", "操作提示",
							JOptionPane.NO_OPTION);
				else if (sprice.length() == 0)
					JOptionPane.showMessageDialog(null, "添加失败,商品价格不能为空!", "操作提示",
							JOptionPane.NO_OPTION);
				else {
					Object str[] = { sno, sname, sprice };
					Connection sin = Dbcon.getconnectin();
					Dbcon.insert(sin, str);
					JOptionPane.showMessageDialog(null, "添加成功!", "操作提示",
							JOptionPane.NO_OPTION);
					dispose();
				}
			}
		}
	}

	class Quit implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			JOptionPane.showMessageDialog(null, "取消成功!", "操作提示",
					JOptionPane.NO_OPTION);
			dispose();
		}
	}
}

/*
 * class MyPanel extends JPanel{ Label lb ;
 * 
 * MyPanel(String s,JTextField jt){ setLayout(new FlowLayout());
 * 
 * lb=new Label(s); add(lb);add(jt); }
 * 
 * }
 */

/*
 * MyPanel p1=new MyPanel("商品号:",jt); MyPanel p2=new MyPanel("商品名称:",jt2); MyPanel
 * p3=new MyPanel("商品价格:",jt3);
 */

二、小目录

package rjgc;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.sql.*;

public class Alterdialog extends JFrame {
	public static final int Width = 320;
	public static final int Heigth = 230;

	Button btn, btn2;
	JTextField jt, jt2, jt3;

	/*
	 * 1
	 */

	public Alterdialog() {
		setSize(Width, Heigth);
		setLocation(820, 200);
		setTitle(new String("修改:"));
		setResizable(false);
		setLayout(new FlowLayout());
		jt = new JTextField(20);
		Label lb = new Label("商品号:");
		btn = new Button("确定");
		btn.addActionListener(new Enter());
		btn2 = new Button("取消");
		btn2.addActionListener(new Quit());
		/*
		 * 2
		 */
		add(lb);
		add(jt);
		// 3
		add(btn);
		add(btn2);

	}

	class Enter implements ActionListener {//修改即先删后加
		public void actionPerformed(ActionEvent e) {
			Container con = getContentPane();
			if (e.getActionCommand().equals("确定")) {
				con.setBackground(Color.red);
				Connection sin = Dbcon.getconnectin();
				String sno = jt.getText();//获取要修改的商品号sno
				int num=Dbcon.delete(sin, sno);//调用删除类 执行删除方法
				if(num==0)		
					JOptionPane.showMessageDialog(null, "信息修改失败!,无该商品号", "信息",
							JOptionPane.INFORMATION_MESSAGE);
				else{
					Tianjiadialog tg = new Tianjiadialog();//添加
				tg.setVisible(true);
				}
			}
		}
	}
	
	class Quit implements ActionListener {
		public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null, "取消成功!", "操作提示",
						JOptionPane.NO_OPTION);
				dispose();
		}
	}
}

/*
 * 1 class MyPanel extends JPanel{ Label lb ;
 * 
 * MyPanel(String s,JTextField jt){ setLayout(new FlowLayout());
 * 
 * lb=new Label(s); add(lb);add(jt); }
 * 
 * }
 */

/*
 * 2 MyPanel p1=new MyPanel("商品号:",jt); MyPanel p2=new MyPanel("商品名称:",jt2);
 * MyPanel p3=new MyPanel("商品价格:",jt3);
 */

// 3add(lb2);add(jt2);add(lb3);add(jt3);

三、查询

package rjgc;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.sql.*;

public class Cxdialog extends JFrame {
	public static final int Width = 320;
	public static final int Heigth = 230;

	Button btn, btn2;
	JTextField jt, jt2, jt3;

	/*
	 * class MyPanel extends JPanel{ Label lb ;
	 * 
	 * MyPanel(String s,JTextField jt){ setLayout(new FlowLayout());
	 * 
	 * lb=new Label(s); add(lb);add(jt); }
	 * 
	 * }
	 */
	public Cxdialog() {
		setSize(Width, Heigth);
		setLocation(820, 200);
		setTitle(new String("查询:"));
		setResizable(false);
		setLayout(new FlowLayout());
		Container con = getContentPane();
		jt = new JTextField(20);
		Label lb = new Label("商品号:");
		btn = new Button("确定");
		btn.addActionListener(new Enter());
		btn2 = new Button("取消");
		btn2.addActionListener(new Quit());
		/*
		 * MyPanel p1=new MyPanel("商品号:",jt); MyPanel p2=new MyPanel("商品名称:",jt2);
		 * MyPanel p3=new MyPanel("商品价格:",jt3);
		 */
		add(lb);
		add(jt);
		// add(lb2);add(jt2);add(lb3);add(jt3);
		add(btn);
		add(btn2);
	}

	class Enter implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			Container con = getContentPane();
			if (e.getActionCommand().equals("确定")) {
				con.setBackground(Color.red);
				Connection sin = Dbcon.getconnectin();
				String sno = jt.getText();
				ResultSet rs = null;
				PreparedStatement stmt = null;
				try {
					stmt = sin
							.prepareStatement("select * from info where sno=?");
					stmt.setObject(1, sno);
					rs = stmt.executeQuery();
					int count = 0;//查询不到记为0,查询得到记为1
					while (rs.next()) {
						String msg = rs.getString("sno") + "\t"
								+ rs.getString("sname") + "\t"
								+ rs.getString("sprice") + "\n";
						JOptionPane.showMessageDialog(null, msg, "查询结果:",
								JOptionPane.NO_OPTION);
						dispose();
						count = 1;//查询得到就记count为1,
					}
					if (count == 0)//查询不到就显示无该商品号
						JOptionPane.showMessageDialog(null, "无该商品号", "查询结果:",
								JOptionPane.NO_OPTION);
					// stmt.close();
					// con.close();
				} catch (SQLException h) {
					// TODO Auto-generated catch block
					h.printStackTrace();
				}
			}
		}
	}

	class Quit implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			JOptionPane.showMessageDialog(null, "取消成功!", "操作提示",
					JOptionPane.NO_OPTION);
			dispose();
		}
	}
}

四、数据库

package rjgc;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.swing.JOptionPane;

public class Dbcon {
	static String url="jdbc:mysql://localhost:3306/wtf?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";//数据库名为wtf
	static String username="root";//数据库用户名
	static String password="";//数据库密码 没有就是空字符串
	static Properties _prop=null;
	
	
	static {
		  _prop = new Properties();
		try {
			String proFilePath = System.getProperty("user.dir") + "\\config.properties";  
			InputStream in = new BufferedInputStream(new FileInputStream(proFilePath));  
			BufferedReader bf = new BufferedReader(new InputStreamReader(in));
			_prop.load(bf);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	
	public final static Connection getconnectin() {
		Connection con = null;// 连接数据库
		if(_prop.containsKey("database")) {				
			password=  _prop.getProperty("database");
		}
		if(_prop.containsKey("username")) {			
			username = _prop.getProperty("username");
		}
		if(_prop.containsKey("username")) {				
			password=  _prop.getProperty("password");
		}
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(url,username,password);
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");// 注册驱动
			con.setCatalog("wtf");// 选择要在其中进行工作的此 Connection对象数据库的子空间(wtf数据库)。
		} catch (SQLException sqle) {
			System.out.println(sqle + "连接错误");
		} catch (Exception e) {
			System.out.println(e + "其他错误");
		}
		return con;//返回Connection对象
	}

	// 添加数据
	public final static void insert(Connection con, Object obj[]) {
		PreparedStatement stmt = null;
		try {
			stmt = con
					.prepareStatement("insert into info(sno,sname,sprice) values(?,?,?)");
			// SQL 语句被预编译并存储在 PreparedStatement 对象中,包含多个 '?' IN 参数占位符的 SQL 语句
			stmt.setString(1, obj[0].toString());// 将指定参数设置为传入的字符串
			stmt.setString(2, obj[1].toString());
			stmt.setString(3, obj[2].toString());
			stmt.execute(); // 执行sql语句
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "失败", "操作提示!",
					JOptionPane.NO_OPTION);
		}
	}

	// 查询数据
	public final static ResultSet query(Connection con) {
		ResultSet rs = null;
		PreparedStatement stmt = null;// sql语句执行对象
		try {
			stmt = con.prepareStatement("select * from info");// 将sql语句发送到数据库返回statement对象
			rs = stmt.executeQuery();// 执行 SQL 查询
			// stmt.close();// 不可关流
			// con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;// 返回结果集
	}

	// 删除数据
	public final static int delete(Connection con, String s) {
		int num = 0;
		try {
			PreparedStatement stmt;
			stmt = con.prepareStatement("delete from info where sno=?");// ?待定通配符
			stmt.setObject(1, s);// 把第一个参数 即? 设置为传进来的String s
			num = stmt.executeUpdate();// 执行sql语句 '删除'功能无返回结果
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return num;
	}

}

五、删除

package rjgc;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.swing.JOptionPane;

public class Dbcon {
	static String url="jdbc:mysql://localhost:3306/wtf?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";//数据库名为wtf
	static String username="root";//数据库用户名
	static String password="";//数据库密码 没有就是空字符串
	static Properties _prop=null;
	
	
	static {
		  _prop = new Properties();
		try {
			String proFilePath = System.getProperty("user.dir") + "\\config.properties";  
			InputStream in = new BufferedInputStream(new FileInputStream(proFilePath));  
			BufferedReader bf = new BufferedReader(new InputStreamReader(in));
			_prop.load(bf);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	
	public final static Connection getconnectin() {
		Connection con = null;// 连接数据库
		if(_prop.containsKey("database")) {				
			password=  _prop.getProperty("database");
		}
		if(_prop.containsKey("username")) {			
			username = _prop.getProperty("username");
		}
		if(_prop.containsKey("username")) {				
			password=  _prop.getProperty("password");
		}
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection(url,username,password);
			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");// 注册驱动
			con.setCatalog("wtf");// 选择要在其中进行工作的此 Connection对象数据库的子空间(wtf数据库)。
		} catch (SQLException sqle) {
			System.out.println(sqle + "连接错误");
		} catch (Exception e) {
			System.out.println(e + "其他错误");
		}
		return con;//返回Connection对象
	}

	// 添加数据
	public final static void insert(Connection con, Object obj[]) {
		PreparedStatement stmt = null;
		try {
			stmt = con
					.prepareStatement("insert into info(sno,sname,sprice) values(?,?,?)");
			// SQL 语句被预编译并存储在 PreparedStatement 对象中,包含多个 '?' IN 参数占位符的 SQL 语句
			stmt.setString(1, obj[0].toString());// 将指定参数设置为传入的字符串
			stmt.setString(2, obj[1].toString());
			stmt.setString(3, obj[2].toString());
			stmt.execute(); // 执行sql语句
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "失败", "操作提示!",
					JOptionPane.NO_OPTION);
		}
	}

	// 查询数据
	public final static ResultSet query(Connection con) {
		ResultSet rs = null;
		PreparedStatement stmt = null;// sql语句执行对象
		try {
			stmt = con.prepareStatement("select * from info");// 将sql语句发送到数据库返回statement对象
			rs = stmt.executeQuery();// 执行 SQL 查询
			// stmt.close();// 不可关流
			// con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;// 返回结果集
	}

	// 删除数据
	public final static int delete(Connection con, String s) {
		int num = 0;
		try {
			PreparedStatement stmt;
			stmt = con.prepareStatement("delete from info where sno=?");// ?待定通配符
			stmt.setObject(1, s);// 把第一个参数 即? 设置为传进来的String s
			num = stmt.executeUpdate();// 执行sql语句 '删除'功能无返回结果
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return num;
	}

}

五、主窗口

package rjgc;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

//这个是主运行程序  可以右键运行这个类
//
public class MainLogin extends JFrame {
	JTextField f1; // 输入用户文本框
	JTextField f2;// 输入密码文本框
	JButton b1;// 登录按钮
	JButton b2;// 重置按钮
	String power;// 表示权限
	String imgePath = "backGround.jpg";
	JPanel p5;// 最外层容器
	Image img = Toolkit.getDefaultToolkit().createImage(imgePath);// 获取默认工具包.
																	// 获取图片像素数据

	MainLogin() {
		Container cp = getContentPane();// 返回此窗体的 contentPane 对象
		Label l1 = new Label("用户:");
		Label l2 = new Label("密码:");

		JPanel p1 = new JPanel();
		JPanel p2 = new JPanel();
		JPanel p3 = new JPanel();
		JPanel p4 = new JPanel();
		p5 = new JPanel() {
			protected void paintChildren(Graphics g) {
				g.drawImage(img, 0, 0, this);// 设置背景图和坐标
				super.paintChildren(g);// 显示图片
			}
		};

		f1 = new JTextField(15);
		f2 = new JPasswordField(15);
		b1 = new JButton("登录");
		b2 = new JButton("重置");
		p1.setBackground(Color.orange);
		p2.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));
		p2.add(l1);// 往轻量级容器里添加不可编辑文本
		p2.add(f1);// 添加可输入文本框
		p2.setBackground(Color.ORANGE);// 设置背景颜色
		p2.setBounds(200, 240, 224, 30);
		p3.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));
		p3.add(l2);
		p3.add(f2);
		p3.setBackground(Color.ORANGE);
		p3.setBounds(200, 340, 224, 30);
		p4.add(b1);
		p4.add(b2);
		p4.setLayout(new FlowLayout(FlowLayout.LEFT,2,2));
		p4.setBackground(Color.ORANGE);
		p4.setBounds(240, 410, 125, 30);
		p5.setLayout(null);// 构造一个新的
							// FlowLayout,它具有居中的对齐方式,水平.垂直间距40
		p5.add(p2);
		p5.add(p3);
		p5.add(p4);
		cp.add(p5, BorderLayout.CENTER);
		b1.addActionListener(new Enter());// 监听 登录按钮事件
		b2.addActionListener(new ReWrite());// 监听 重置按钮事件
		addWindowListener(new winClose());// 监听窗口处理事件
	}

	public static void main(String[] args) {
		MainLogin log = new MainLogin();
		log.setIconImage(Toolkit.getDefaultToolkit().createImage("icon.jpg"));// 登录界面标题logo图片
		String loginPageTitle = "商品信息管理系统";
		if(Dbcon._prop.containsKey("frameTitle")) {
			loginPageTitle=(String) Dbcon._prop.get("loginPageTitle");
		}
		log.setTitle(loginPageTitle);
		log.setLocation(600, 300); // 方框出现在屏幕的位置
		log.setSize(750, 548); // 调整登录框大小
		log.setResizable(false);// 设置为不可调整窗口大小
		log.setVisible(true); // 是否可视化 

	}

	class Enter implements ActionListener {
		@SuppressWarnings("deprecation")
		public void actionPerformed(ActionEvent e)// 重写事件反映方法
		{
			MainLogin log = new MainLogin();// 持有对象引用
			if ((f1.getText()).equals("admin") && (f2.getText()).equals("123")) {
//				JOptionPane.showMessageDialog(null, "登录成功!用户权限是adimistrator");// 弹出要求用户提供值或向其发出通知的标准对话框
				power = "adminstrator";// 赋予管理员权限
				Qframe frame = new Qframe();// 验证成功后就建对象调用构造方法连接数据库
				frame.setIconImage(Toolkit.getDefaultToolkit().createImage(
						"icon.jpg"));// 进入管理系统的logo图片
				frame.setLocation(400, 200);
				frame.setSize(500, 285);
				frame.setResizable(false);
				frame.setVisible(true);
				dispose();// 释放此图形的上文以及它使用的所有系统资源,即实现关闭弹出新窗口后关闭上个窗口
			} else if ((f1.getText()).equals("xues")
					&& (f2.getText()).equals("123")) {
				JOptionPane.showMessageDialog(null, "登录成功!用户权限是user");// 弹出要求用户提供值或向其发出通知的标准对话框
				power = "adminstrator";
				Qframe frame = new Qframe();
				frame.setIconImage(Toolkit.getDefaultToolkit().createImage(
						"img1.jpg"));
				frame.setLocation(400, 200);
				frame.setSize(750, 543);// 500/285
				frame.setResizable(false);
				frame.setVisible(true);
				dispose();
			} else
				JOptionPane.showMessageDialog(null, "登录失败,请重新登录!");
		}
	}

	class ReWrite implements ActionListener {// 监听器实现接口
		public void actionPerformed(ActionEvent e)// 传入事件信息对象
		{
			f1.setText("");// 把文本中的内容清空起到重置效果
			f2.setText("");
			f1.requestFocus();// 请求获取输入焦点,即点击完重置 光标自动跳回输入用户框
		}
	}

	class winClose extends WindowAdapter// 窗口正处在关闭过程中时调用。 //最终exit 退出程序
	{
		public void windowClosing(WindowEvent e) { // getwindow 返回事件的发起方
			(e.getWindow()).dispose();// 释放由此 Window、其子组件及其拥有的所有子组件所使用的所有本机屏幕资源。
			System.exit(0);// 最终exit 退出程序
		}
	}
}

六、项目成果展示

请看vcr

七、项目的踩坑集(知识集)

一、环境安装

一、安装JDK步骤及配置JDK环境变量步骤省略。

二、安装Tomcat(提前请先安装JDK)

三、安装官网:https://tomcat.apache.org/download-80.cgi

也直接点击:https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.99/bin/apache-tomcat-8.5.99-windows-x64.zip
Tomcat很特殊,各个版本之间可能会相互不兼容。这里示例安装8.5的版本。

image-20240320155442017

点击tomcat8后根据自己的电脑选择相应的型号(我是64位电脑)

下载速度很快。将下载的文件解压到想放置的文件下,目录中不能包含中文(建议最好不要放C盘)
这里以E盘为例

四、配置环境变量
右击“我的电脑”>>选择“属性”>>单击左侧栏“高级系统设置”>>“高级”>>“环境变量”

image-20240320155504765选择新建系统变量
变量名:CATALINA_HOME
变量值:E:Softwareapache-tomcat-8.5.72 (填Tomcat的安装位置 即根目录)

找到系统变量下的Path变量,点击编辑
变量名:Path
变量值:直接复制,添加在原变量值的末尾

image-20240320155600162

五、验证环境
按下window+R键盘。如下图

按照网上教程,在tomcat目录in目录中 ,运行命令行 ,输入 service.bat install
提示“‘E:Softwareapache-tomcat-8.5.72’ 不是内部或外部命令,也不是可运行的程序或批处理文件”

image-20240320155624828

解决办法:
找到tomcat按照目录下的bin文件夹,双击startup.bat,它会自动打开如下控制台界面。

最后,

这时候不要关闭控制台界面,打开浏览器,输入http://localhost:8080,出现Tomcat的网页,证明安装并配置成功!最后关闭控制台,关闭控制台即关闭Tomcat服务。(记得关闭防火墙!)

六、在eclipse配置Tomcat8.5
打开eclipse,点击菜单栏window>>preference

在preferences中找到Server>>点击Runtime Environments >>点击Add

选择自己所安装的Tomcat版本

遇到问题

eclipse无法配置tomcat8及其以上版本
解决 Eclipse不支持tomcat9
前言:

我在配置eclipse+tomcat时,因为eclipse版本问题,里面没有Server选项;

好不容易找到了添加工具包,却发现没有tomcat;

一番功夫下来,新的工具包却只支持到tomcaHt8。

最后找到合适的方法,共享给大家。
解决方法:

1、在eclipse下: Help -> Eclipse Marketplace

2、搜索:apache-tomcat

3、发现两个扩展包,如图:

这里写图片描述

4、解释一下:

第一个JST Server Adapters 安装后只有tomcat8,应该是比较早的扩展了

第二个JAVA EE Developer Tools 东西有些多,不过好歹能用,顺带把其他工具更新一下。

5、安装过程有些慢,耐心等待。安装结束,会弹出提示,大概意思是有配置更改,需要重启。确认过后eclipse自动关闭,你再打开就可以在windows->perferences下找到Server -> Runtime Environment,添加tomcat9了。

解决办法:Eclipse -> help -> Install New Software -> 在Work with中输入:Oxygen - http://download.eclipse.org/releases/oxygen,注意“Oxygen”是Eclipse版本类型,根据你的版本修改对应红色文字内容。->
Add ->在最后的Web,XML,Java EE and OSGi Enterprise Development 下选择 勾选
JST Server Adapters 和 JST Server Adapters Extentions,然后Next。
注意事项:
1)Install窗口,不要勾选Contact all update sites during install to find required software,否则下载速度会比较慢。
2)查看Eclipse版本:help -> About Eclipse -> Version。

二、快捷键

(1)快捷键的概念

​ 快捷键,又叫快速键或热键,指通过某些特定的按键、按键顺序或按键组合;来完成一个操作。很多快捷键往往

与Ctrl键、Shift键、Alt键、Fn键以及Windows平台下的Windows键和Mac机上的Meta键等配合使用。利用快捷键可以

代替鼠标做一些工作。

(2)Eclipse中的常用快捷键

img

img

​ Ctrl+S:Ctrl+C、Ctrl+X、Ctrl+V、Ctrl+Z这五个我们就不再多说,这是我们很常用的。

​ Ctrl+D:删除当前行或者多行。

​ Ctrl+F:查询与替换,按下后出现Find/Replace对话框,我们按照上面的选择和更改即可实现。

img

​ Ctrl+N:新建向导。按下后,出现New对话框,我们可以选择一个新建的任何文件类型或项目。

img

​ Ctrl+H:Java文件查询。按下后,出现Search对话框,我们输入要查找的Java文件的名称即可实现。

img

​ 对于其他的快捷键我们可以在书写代码的过程中逐渐使用到,我们多加练习即可掌握。

​ 想要了解更多的可以参考:黑马程序员——eclipse开发工具中常用快捷键–提升开发效率。

(3)设置快捷键与修改快捷键

​ 原因:

​ 1)与其他软件的快捷键冲突。

​ 2)不符合个人使用习惯。

​ 设置和修改快捷键的方法是:Window->Preferences->General->Keys

img

代码补全

(1)设置触发器

​ 所谓的自动触发器就是认点操作符就会触发属性或方法提示。我们也可以设置任意字符触发提示,比如我们要求

只要输入一个大小写字母和点操作符都会自动触发属性或方法提示。

​ 操作的方法就是:Window->preferences->Java->Editor->Content Assist

img

​ 我们可以在代码中演示一下:

img

(2)使用Eclipse提示补全代码

1)未导入的类

​ 输入语句:Date date = new Date();,那么Eclipse就会出现提示未导入的类,我们选择导入的类即可。

img

img

2)未处理的异常

​ 在main方法中输入Class.forName(“”);就会抛出未处理的异常,我们选择try/catch处理快:

img

img

3)未处理的抽象方法

​ 在代码中新建一个实现Runnable接口的MyThread类,就会出现未处理的抽象方法,我们选择重写即可。

​ class MyThread implements Runnable{}

img

img

(3)使用代码模板产生代码

​ 只需要输入少量字符串即可产生相应的代码。下面的是很常用的几个。

​ 如果我们输入以下的少两字符串就会使用代码模板产生代码:

1)main

​ 输入main,出现代码补全提示,选中合适的,敲击回车即可。

img

img

2)syso

​ 输入syso,出现代码补全提示,选中合适的,敲击回车即可。

img

img

3)for

​ 输入for,出现代码补全提示,选中合适的,敲击回车即可。

img

img

4)fore

​ 输入fore,出现代码补全提示,选中合适的,敲击回车即可。

img

img

代码补全操作

(1)成员排序

​ 在编辑器上右击找到Source,选择Sort Members,也可以在菜单栏上点击Source,选择其中的Sort Members,

出现Sort Members对话框,点击Members Sort Order超链接,出现Preferences对话框,保持默认即可。在Sort

Members对话框选择第二个可以进行成员排序,我们不再进行演示。

img

(2)代码清理

​ 编辑器上右击找到Source,选择Clean Up,出现Clean Up对话框,点击其中的Clean Up超链接,打开Clean Up

对话框,对于设置,我们保持默认即可。比如我们的代码中有多余的import.io.*;

img

img

(3)重写/实现方法

​ 在编辑器上右击找到Source,选择Override/Implement Methods,出现Override/Implement Methods对话框,我

们可以选择要重写的方法。假如我们要实现Map接口,需要实现的方法可供选择。

img

(4)产生getter/setter方法

​ 在编辑器上右击找到Source,选择Generate Getters andSetters,出现Generate Getters andSetters对话框,我

们可以选择要实现产生getter/setter方法的私有属性。

img

(5)产生代理方法

​ 在编辑器上右击找到Source,选择Generate Delegate Methods,出现Generate Delegate Methods对话框,我

们可以选择要实现产生代理方法test()的成员变量。

img

(6)产生toString、equal、shashCode方法

​ 在编辑器上右击找到Source,选择Generate hashCode() and equals(),出现Generate hashCode() and equals()

对话框,我们可以选择要实现这两个方法age的成员变量。

img

​ 在编辑器上右击找到Source,选择Generate toString(),出现Generate toString()对话框,我们可以选择要实现

这个方法age的成员变量。

img

(7)产生构造方法

​ 在编辑器上右击找到Source,选择Generate Constructor using Fields,出现Generate Constructor using Fields

对话框,我们可以选择要实现构造方法的成员变量。

img

(8)提取字符串

​ 在编辑器上右击找到Source,选择Externalize String,出现Externalize String对话框,我们可以选择要更改的字

符串。

img

(9)代码补全操作

1)代码样式(风格):

​ Window->preferences->Java->Code Style

img

2)代码格式化:

​ Window->preferences->Java->Code Style->Formatter

img

(10)Java代码模板

1)代码注释模板

​ Window->preferences->Java->Code Style->Code Templates

img

img

2)代码补全模板

​ Window->preferences->Java->Editor->Templates

img

Server Apache-tomcat7 failed to start.

在这里插入图片描述
tomcat运行报错Server “tomcat名称”failed to start.我这边最简单的方法就是把项目先Remove
然后Publish一下
在这里插入图片描述
然后再把项目加进去
在这里插入图片描述
然后重新再Publish一下,就可以正常启动了
ps:
如果还是不行,请右击项目,找到java构建路径,在右边选择“库”,然后点击Add Library…,选择Server Runtime,点击next,然后选择你这个项目所部署的tomcat文件,然后点击完成,再重新部署一下就好了!

java打包

打成jar部署运行
这个方法需要单独安装JDK,然后在命令行下启动,可以单独制作启动脚本。
window下bat启动脚本

1、如果依赖包也打成同一个jar

@echo off
@REM 如果没有设置系统环境变量,如果在脚本中指定JDK
SET JAVA_HOME=C:\Program Files\Java\bellsoft\jdk-17.0.9
SET PATH=%JAVA_HOME%/bin;%PATH%;

@REM 936设为GBK编译, 65001设为UTF编译
chcp 65001
java -jar DFDiff-1.2.0-jar-with-dependencies.jar

2、如果依赖包独立,本文不使用该方法,仅供打包其它项目时参考

@rem windows
@echo off
set project_home=%~dp0
echo %project_home%
setlocal enabledelayedexpansion
SET class_path=%project_home%DFDiff-1.2.0-jar-with-dependencies.jar
for /r %project_home%/lib %%i in (*.jar) do (
rem echo %%i
set class_path=!class_path!;%%i
)
echo %class_path%
java -Xms512m

方法一是打成Jar,使用shell脚本启动是最常用的打包运行方式,打包发布不会存在兼容问题。运行时会显示两个进程:shell进程与java进程。
方法二是在方法一基础上,简化shell的启动方式,但是启动器需要在每个平台上编译一次。运行时会显示两个进程:启动器进程与java进程。
方法三是JDK自带的工具打包,与方法二相比,省掉自己编写启动器的工具。运行时会显示两个相同名称的应用进程。
方法四是目前新的方式,能显著提高性能,但由于应用使用反射等技术原因,可能需要手动编写反射类,与前边3种方法相比,有一点的上手难度,同样也由此造成与前边三个方法相比,兼容性相对差。运行时只显示一个进程。

java程序打包

在Java中,将程序打包成一个可执行的JAR文件通常涉及以下步骤:

  1. 编译Java源代码:使用javac命令将所有.java源文件编译成.class字节码文件。
  2. 打包成JAR:使用jar命令将编译后的.class文件和所需的资源文件打包进一个JAR文件中。

以下是一个简单的例子:

假设您的Java源文件是Main.java,位于当前目录下。

  1. 编译Java源代码:
javac Main.java
  1. 打包成JAR文件(假设JAR文件名为app.jar):
jar cvf app.jar *

如果您的程序有主清单属性(例如,在Main.java中有main方法的类声明了Main-Class属性),您可以在jar命令中指定这个属性:

jar cvfe app.jar com.example.Main Main.class

在这个命令中,com.example.Main是包含main方法的类的全限定名,Main.class是要打包的类文件列表。

这样,您就成功地将Java程序打包成了一个可执行的JAR文件。要运行这个JAR文件,您可以使用java -jar命令:

java -jar app.jar

image-20240329085814204

八、项目总结与收获

一、个人方面

学会系统性的搭建项目结构

项目分工,怎么合理分配资源

学会用文章记录自己的学习之旅

image-20240329010016571

image-20240329010053329

能够合理组织数据提高效率

提出问题

image-20240329010249502

找到解决办法

二、团队方面

收获

​ 技术技能的提升:通过不断的实践和错误修正,团队成员在特定领域的技术能力有了显著提高。

​ 解决问题的能力:面对问题时,成员学会了如何分析问题、制定解决方案并实施。

​ 团队合作精神:共同经历挑战和失败,增强了团队成员之间的沟通和协作。

​ 换位思考:能够从实际角度方向出发,为了以后更好的发展

​ 忍耐力和韧性:不断试错的过程锻炼了成员的耐心和坚持到底的决心。

寄语

  • 首先要勇敢尝试,不要怕
  • 失败了没关系,满屏bug也没关系,只要去做就会有收获,不管或多或少,浙大翁恺说过,计算机无论什么语言就是不断熟悉的过程
  • 不要欺骗别人,更不要欺骗自己,路是要自己去走的,经验是要自己去积累的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/500499.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GEE实践应用|热岛效应(一)地表温度计算

目录 1.学习目标 2.理论介绍 3.从MODIS获得地表温度 4.从Landsat卫星获得地表温度 1.学习目标 ①了解如何使用GEE计算地表温度 2.理论介绍 城市化涉及用建筑物、道路和停车场等建筑结构取代自然景观。这种土地覆盖的改变也改变了土地表面的特性。这些变化的范围从表面反射和…

【ERP原理与应用】作业·思考题三、四

思考题三 P77第四章3, 6,8 3.生产规划的基本内容是什么? 生产规划是根据企业未来一段时间内预计资源可用量和市场需求量之间的平衡所制定的概括性设想是根据企业所拥有的生产能力和需求预测,对企业未来较长一段时间内的产品、产…

基于springboot和vue的在线图书管理系统

目 录 摘要…………………………………………………………………………………………………………1 引言/引论 …………………………………………………………………………………………………2 1.绪论……………………………………………………………………………………3 1.1 背…

Go语言爬虫实战(线程池)

Go语言爬虫实战 目标 利用go语言爬取指定网站的图片。实现爬取网站任意页面所有所需的图片。实现使用go语言线程池开启多个线程爬取图片内容。最后实现创建多个文件夹存储图片。 爬取网站图片 步骤 对指定URL发去GET请求,获取对应的响应。 resp, err : http.Get(…

【STM32嵌入式系统设计与开发】——13WWDG(窗口看门狗应用)

这里写目录标题 一、任务描述二、任务实施1、WWDG工程文件夹创建2、函数编辑(1)主函数编辑(2)USART1初始化函数(usart1_init())(3)USART数据发送函数( USART1_Send_Data(&#xff09…

单词频次-第12届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第44讲。 单词频次&#xf…

大模型重塑电商,淘宝、百度、京东讲出新故事

配图来自Canva可画 随着AI技术日渐成熟,大模型在各个领域的应用也越来越深入,国内互联网行业也随之进入了大模型竞赛的后半场,开始从“百模大战”转向了实际应用。大模型从通用到细分垂直领域的跨越,也让更多行业迎来了新的商机。…

Python学习:lambda(匿名函数)、装饰器、数据结构

Python Lambda匿名函数 Lambda函数(或称为匿名函数)是Python中的一种特殊函数,它可以用一行代码来创建简单的函数。Lambda函数通常用于需要一个函数作为输入的函数(比如map(),filter(),sort()等&#xff0…

boost::asio::ip::tcp/udp::socket::release 函数为什么限制 Windows 8.1 才可以调用?

如本文题目所示,这是因为只有在 Windows 8.1(Windows Server 2012 RC)及以上 Windows 操作版本才提供了运行时,修改/删除完成端口关联的ABI接口。 boost::asio 在 release 函数底层实现之中是调用了 FileReplaceCompletionInform…

(完结)Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(三)项目优化

本文参考自 Springboot3微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第(三)章——项目优化,本篇将讲解该项目最后的优化部分以及一些压测知识点 本章目录 一、压力测试-高并发优化前后的性能对比1.压力测试相关…

Modelsim手动仿真实例

目录 1. 软件链接 2. 为什么要使用Modelsim 3. Modelsim仿真工程由几部分组成? 4. 上手实例 4.1. 新建文件夹 4.2. 指定目录 4.3. 新建工程 4.4. 新建设计文件(Design Files) 4.5. 新建测试平台文件(Testbench Files&…

H7310 线性恒流调光芯片 支持24V30V48V60V100V转3.3V5V12V1.5A 外围简单 性价比高

线性恒流调光芯片是一种能够将输入电压稳定转换为恒定电流输出的电子设备,同时支持调光功能。这种芯片通常具有较高的效率和稳定性,适用于LED照明、显示屏等领域。 针对您提到的支持24V、30V、48V、60V、100V转3.3V、5V、12V,并且能够提供1.…

二十九 超级数据查看器 讲解稿 查询复用

二十九 超级数据查看器 讲解稿 查询复用 ​点击此处 以新页面 打开B站 播放当前教学视频 点击访问app下载页面 百度手机助手 下载地址 大家好,今天我们讲一下超级数据查看器的查询复用功能,这是新版本要增加的功能,这讲是预告。 先介绍…

数据可视化Grafana Windows 安装使用教程(中文版)

1.跳转连接 天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/site?url 2.下载应用程序 官网地址:Grafana get started | Cloud, Self-managed, Enterprisehttps://grafana.com/get/ 3.修改配置文件 grafana\conf\defaults 4.启动\bin\目录下serve应用程序 浏…

机器学习——降维算法-主成分分析(PCA)

机器学习——降维算法-主成分分析(PCA) 在机器学习领域,主成分分析(Principal Component Analysis,简称PCA)是一种常用的降维技术,用于减少数据集中特征的数量,同时保留数据集的主要…

尾矿库在线安全监测:提升矿山安全水平

在矿山安全领域,尾矿库的安全管理尤为关键。尾矿库作为矿山生产链条的重要环节,其稳定性不仅关系到生产活动的持续进行,更直接影响着周边环境和人民群众的生命财产安全。因此,尾矿库的安全监测显得尤为重要。近年来,随…

YOLOv9改进策略 : C2f改进 | 引入YOLOv8 C2f结构

💡💡💡本文改进内容:应订阅者需求,如何将YOLOv8 C2f结构引入到YOLOv9 💡💡💡C2f层是一种特殊的卷积层,用于将不同尺度的特征图融合在一起,以提高目标检测的准…

XXE漏洞知识及ctfshow例题

XXE漏洞相关知识 XXE全称为XML Enternal Entity Injection 中文叫xml外部实体注入 什么是xml 简单了解XML: (xml和html的区别可以简易的理解成:xml是用来储存数据和传输数据的而html是用来将数据展现出来) XML 指可扩展标记语…

UE5数字孪生系列笔记(三)

C创建Pawn类玩家 创建一个GameMode蓝图用来加载我们自定义的游戏Mode新建一个Pawn的C,MyCharacter类作为玩家,新建一个相机组件与相机臂组件,box组件作为根组件 // Fill out your copyright notice in the Description page of Project Set…

【力扣】300. 最长递增子序列(DFS+DP两种方法实现)

目录 题目传送最长递增子序列[DFS 方法]DFS方法思路图思路简述代码大家可以自行考虑有没有优化的方法 最长递增子序列[DP]方法DP方法思路图思路简述代码方案 题目传送 原题目链接 最长递增子序列[DFS 方法] DFS方法思路图 思路简述 对于序列中的每一个数字只有选择和不选择两…