目录
一、实践目的
熟练掌握Java、JavaFX、数据库基础知识,并应用IntelliJ IDEA 2021.2、JavaFX Scene Builder 2.0、SQLyog Community 技术开发实现项目“东软工资管理系统”。
二、实验环境
开发技术:Java基础知识和环境配置、Java集合、异常处理、异常机制(异常的结构、异常处理的机制)、开发流程(MVC)、Java数据库连接技术(jdbc)、Java FX Scene builder
使用
开发环境:
Java编程语言
IDEA(java编程语言的集成开发环境)
SQLyog(图形化管理MYSQL数据库的工具)
MySQL5.1.15
Java FX Scene builder
三、实验内容
第一阶段(基础信息维护):
部门相关界面的绘制
第一步:绘制部门界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,VBox用于把下半部分划分成垂直的两部分,HBox水平摆放控件。
其中表格中的表头信息有:部门编号、部门名称、人员编制数、备注
第二步:显示部门页面
在MainController中传入ImportInfoView对象,用于切换主页面中的布局内容
在MainApp中获取MainController,把ImportInfoView传递过去
完成显示部门页面的逻辑
部门表格中的内容
第一步:创建数据库及部门表
创建数据库的sql语句
创建表格
查看所有表格
插入三条数据
查询表中的数据
创建实体类Dept
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
编写Dao及其实现类
该接口声明操作表dept的增删改查的方法
实现DeptController的逻辑
部门信息维护
-
新建部门
第一步:对话框界面绘制
DeptDialogView.fxml,该视图既有新建部门的功能,又有更新部门的功能,如果是新建部门的话,输入框为空;如果是更新部门的话输入框回显部门信息。
第二步:完成DeptDialogController的编写
该对话框承担了要完成新建部门和更新部门信息的任务
第三步:表写Dao层
-
更新部门
第一步 : 准备好dialog
第二步: 实现
onUpdateDept
方法
第三步:修改实体类Dept,实现数据的双向绑定
-
删除部门
第一步:实现deleteById方法
第二步:在控制类中将选中的部门信息从列表中移除,并调用Dao实现中的deleteById方法
-
查询部门
第一步:实现querByName方法
第二步:在控制类中获取TextField获得的关键词进行判断给予相应结果查询
职位信息维护
-
数据库表
创建数据库及职位表
创建数据库的sql语句
创建表格
查看所有表格
插入三条数据
查询表中的数据
绘制界面
第一步:绘制职位界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,VBox用于把下半部分划分成垂直的两部分,HBox水平摆放控件。
其中表格中的表头信息有:职位编号、职位名称、备注
第二步:显示职位页面
显示界面(在MainController中添加一下方法,用于显示职位信息界面)
在MainController中传入mainView对象,用于切换主页面中的布局内容
在MainApp中获取MainController,把mainView传递过去
完成显示职位页面的逻辑
编写控制器
JobController控制器
JobEditDialogController
控制器
实体类Job
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
-
数据访问层Dao
该接口声明操作表job的增删改查的方法
实现JobController的逻辑
实现类
完成操作表job的增删改查的方法
-
新建职位
第一步:对话框界面绘制
JobEditDialogView.fxml,该视图既有新建部门的功能,又有更新部门的功能,如果是新建部门的话,输入框为空;如果是更新部门的话输入框回显部门信息。
第二步:完成JobEditDialogController的编写
该对话框承担了要完成新建部门和更新部门信息的任务
第三步:表写Dao层
-
更新部门
第一步 : 准备好dialog
第二步: 实现
onUpdate
Job方法
第三步:修改实体类Job,实现数据的双向绑定
-
删除部门
第一步:实现deleteById方法
第二步:在控制类中将选中的部门信息从列表中移除,并调用Dao实现中的deleteById方法
-
查询部门
第一步:实现querByName方法
第二步:在控制类中获取TextField获得的关键词进行判断给予相应结果查询
员工信息维护
-
绘制界面
第一步:绘制员工界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,VBox用于把下半部分划分成垂直的两部分,HBox水平摆放控件。
其中表格中的表头信息有:员工编号、员工姓名、所属部门、职位、邮箱
第二步:显示员工页面
显示界面(在MainController中添加一下方法,用于显示职位信息界面)
在MainController中传入mainView对象,用于切换主页面中的布局内容
在MainApp中获取MainController,把mainView传递过去
完成显示员工页面的逻辑
-
数据库表
创建数据库及职位表
创建数据库的sql语句
创建表格
查看所有表格
插入三条数据
查询表中的数据
-
编写控制器
EmpController控制器
Emp
EditDialogController
控制器
实体类Emp
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
-
数据访问层Dao
该接口声明操作表Emp的增删改查的方法
实现EmpController的逻辑
-
实现类
完成操作表emp的增删改查的方法
-
新建员工
第一步:对话框界面绘制
EmpEditDialogView.fxml,该视图既有新建部门的功能,又有更新部门的功能,如果是新建部门的话,输入框为空;如果是更新部门的话输入框回显部门信息。
第二步:完成EmpEditDialogController的编写
该对话框承担了要完成新建部门和更新部门信息的任务
第三步:表写Dao层
-
更新部门
第一步 : 准备好dialog
第二步: 实现
onUpdate
Emp方法
第三步:修改实体类Emp,实现数据的双向绑定
-
删除部门
第一步:实现deleteById方法
第二步:在控制类中将选中的部门信息从列表中移除,并调用Dao实现中的deleteById方法
-
查询部门
第一步:实现querByName方法
第二步:在控制类中获取TextField获得的关键词进行判断给予相应结果查询
第二阶段(工资数据维护):
固定工资相关界面的绘制
-
第一步:绘制员工工资统计报表界面内容
首先用SplitePane用于把页面划分出上下比例0.8的两部分,其中上半部分使用了TableView控件,其中包含5列TableColumn列表(员工编号、员工姓名、基本工资、餐饮补贴、交通补贴);下半部分采用HBox水平摆放控件,其中包含4个Label、3个ChoiceBox、1个TextField、2个button。
-
第二步:显示员工工资统计报表页面
在MainController中传入showFixedSalaryVIew对象,用于切换主页面中的布局内容
在MainApp中获取MainController,把showFixedSalaryVIew传递过去完成显示部门页面的逻辑
固定工资表格中的内容
在数据库中进行多表联查并导出
创建实体类FixedSalary
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
编写DeptDao及其实现类
该接口声明操作表dept的更新查询的方法
实现FixedSalaryController的逻辑
部门信息维护
-
更新工资项
第一步 : 准备好dialog
第二步: 实现
onUpdateDept
方法
第三步:修改实体类
FixedSalary
,实现数据的双向绑定
-
查询部门
第一步:实现querByName方法
第二步:在控制类中获取TextField获得的关键词进行判断给予相应结果查询
导入数据维护
-
数据库表
在数据库中进行多表联查并导出
绘制界面
第一步:绘制职位界面内容
首先用SplitePane用于把页面划分出上下比例0.8的两部分,HBox水平摆放控件。其中用了tableview控件,其中上半部分使用了TableView控件,下半部分采用HBox水平摆放控件,其中包含3个button、3个Label、3个ChoiceBox。
其中表格中的表头信息有:员工编号、员工姓名、病假天数、事假天数、迟到天数、早退天数、加班天数、年份、月份
第二步:显示职位页面
显示界面(在MainController中添加一下方法,用于显示导入信息信息界面)
在ImportInfoController中传入ImportInfoView对象,用于切换主页面中的布局内容
在MainApp中获取ImportInfoController,把ImportInfoView传递过去
完成显示职位页面的逻辑
-
编写控制器
ImportInfoController
控制器
ImpotInfoEditDialogController
控制器
实体类
ImportInfo
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
-
数据访问层Dao
该接口声明操作表ImportInfoDao的增删改查的方法
实现ImportInfoController的逻辑
-
实现类
完成操作表ImportInfo的增删改查的方法
-
数据编辑
第一步 : 准备好dialog
第二步: 实现
onUpdate
Job方法
第三步:修改实体类Job,实现数据的双向绑定
工资计算
-
数据库表
在数据库中进行多表联查并导出
绘制界面
第一步:绘制职位界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,HBox水平摆放控件。
其中表格中的表头信息有:员工编号、员工姓名、病假天数、事假天数、迟到天数、早退天数、加班天数、年份、月份
第二步:显示职位页面
显示界面(在MainController中添加一下方法,用于显示导入信息界面)
在MainController中传入ImportInfoView对象,用于切换主页面中的布局内容
在MainApp中获取MainController,把ImportInfoView传递过去
完成显示职位页面的逻辑
-
编写控制器
SalaryDealController
控制器
-
实体类
ImportInfo
该类的对象用于存储表中的记录数据,一条记录对应该类的一个对象
-
数据访问层Dao
该接口声明操作表RealSalaryDao的计算工资的方法
实现SalaryDealController的逻辑
-
实现类
完成操作表RealSalary的增删改查的方法
第三阶段(报表管理):
部门年度/月度统计报表
-
数据库表
在数据库中进行多表联查并导出
绘制界面
第一步:绘制职位界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,HBox水平摆放控件。
其中表格中的表头信息有:部门名称、员工编号、员工姓名、实发工资
第二步:显示员工工资统计报表
显示界面(在MainController中添加一下方法,用于显示导入信息信息界面)
在
MainController
中传入ExportEmpFormView对象,用于切换主页面中的布局内容
在MainApp中获取
MainController
,把ExportEmpFormView传递过去
完成显示职位页面的逻辑
-
编写控制器
ExportEmpFormController
控制器
实体类
EmpForm
员工报表对应的实体类,声明对象,并双向绑定,调用getset、toString方法。
-
数据访问层EmpFormDao
员工报表访问接口,查询所有的员工工资信息,根据员工姓名去查找员工报表。
-
实现类EmpFormDaoImpl
实现EMPFormDao里面的方法。
-
通过员工姓名查询该员工信息报表
第一步:数据显示
在ExportEmpFormControlle中,方法initialize()绑定属性和列,查询数据加载报表数据。
第二步: 通过员工姓名查询该员工信息报表
在ExportEmpFormControlle中,方法find(),如果输入为空的姓名,则会弹出警告;如果输入的员工姓名不存在,也会弹出相应的警告。输入正确,则查询出员工的信息报表。
第三步:将数据dataList导出在excel文件中
在ExportEmpFormControlle中,方法onexportForm(),dataList通过POI导出到excel中。首先判断dataList是否为空,不为空,①创建一个与excel文件对应的对象XXSFWorkbook ②创建一个表格XSSFSheet③创建首行XXSFRow(headerRow)④创建首行单元格,用数组把表头写进去,再用循环把dataList里面的数据放进去,这里有三个循环。⑤保存文档,先定义文档路径,它会自动生成excel,OutputStream IO流,给workbook存入write ,最后关闭os
四、实验步骤(图文方式叙述)
第一阶段
(基础信息维护)
:
部门相关界面的绘制
第一步:绘制部门界面内容
其中用了tableview控件,SplitePane用于把页面划分出上下两部分,VBox用于把下半部分划分成垂直的两部分,HBox水平摆放控件。
其中表格中的表头信息有:部门编号、部门名称、人员编制数、备注
第二步:显示部门页面
在MainController中传入mainView对象,用于切换主页面中的布局内容
private BorderPane mainView; public void setMainView(BorderPane mainView) {
|
在MainApp中获取MainController,把mainView传递过去
完成显示部门页面的逻辑
/**
|
效果图如下:
部门表格中的内容
第一步:创建数据库及部门表
# 创建数据库的sql语句: create database neuedu_system default character set utf8;
# 选择数据库 USE neuedu_system;
# 创建表格 CREATE TABLE dept( dept_id VARCHAR(10) NOT NULL, detp_name VARCHAR(4) DEFAULT NULL, dept_number INT(10) DEFAULT NULL, dept_comm VARCHAR(255) DEFAULT NULL );
# 查看所有表格 SHOW TABLES;
# 查看表结构 DESC dept;
# 插入一条数据 INSERT INTO dept VALUES(‘001’, ‘研发部’, 100, ‘该部门主要负责产品的技术研发工作’);
# 查询表中的数据 SELECT * FROM dept; |
创建实体类Dept
/** private String deptId; public Dept() { public Dept(String deptId, String deptName, Integer deptNumber, String deptComm) { public String getDeptId() { public void setDeptId(String deptId) { public String getDeptName() { public void setDeptName(String deptName) { public Integer getDeptNumber() { public void setDeptNumber(Integer deptNumber) { public String getDeptComm() { public void setDeptComm(String deptComm) { @Override
|
编写Dao及其实现类
/** /** /** /** /** /**
|
public class DeptDaoImpl implements DeptDao { @Override //把数据从结果集中取出,存入到Dept类的某个集合中去,然后返回 //resultSet.next(); //判断是否有下一条数据, 如果有数据就返回true Dept dept = new Dept(); //关闭连接 JdbcUtil.close(connection, statement, resultSet);
@Override @Override @Override @Override
|
第四步:实现DeptController的逻辑
public class DeptController { @FXML //特殊的集合 private DeptDao deptDao = new DeptDaoImpl(); /** try {
|
基础信息维护
主要完成针对于部门信息的管理功能:新建部门、更新部门、删除部门、查询部门
部门信息维护
新建部门
第一步:对话框界面绘制
DeptDialogView.fxml,该视图既有新建部门的功能,又有更新部门的功能,如果是新建部门的话,输入框为空;如果是更新部门的话输入框回显部门信息。
第二步:完成DeptDialogController的编写
/** @FXML private Dept dept; //如果该对象为空,说明操作的是新建部门;否则操作的是更新部门 //dao public void setDept(Dept dept) { //数据的回显,当点击更新部门的时候,对话框中要显示更新部门的信息(选中的) public void setDataList(ObservableList dataList) { public void setStage(Stage stage) { @FXML //要把新建信息的对象dept放入到那个特殊的集合中去 } //关闭对话框 @FXML
|
第三步:表写Dao层
@Override
|
更新部门
第一步 : 准备好dialog
第二步: 实现onUpdateDept方法
@FXML Stage stage = new Stage(); //子 //设置dialog的controller对象 stage.showAndWait();
|
第三步:修改实体类Dept,实现数据的双向绑定
public class Dept { private StringProperty deptId; //双向绑定 public Dept() { } public StringProperty deptIdProperty(){ public StringProperty deptNameProperty(){ private IntegerProperty deptNumberProperty(){ public StringProperty deptCommProperty(){ public String getDeptId() { public void setDeptId(String deptId) { public String getDeptName() { public void setDeptName(String deptName) { public Integer getDeptNumber() { public void setDeptNumber(Integer deptNumber) { public String getDeptComm() { public void setDeptComm(String deptComm) { @Override
|
删除部门
第一步:实现deleteById方法
|
第二步:在控制类中将选中的部门信息从列表中移除,并调用Dao实现中的deleteById方法
|
查询部门
第一步:实现querByName方法
|
第二步:在控制类中获取TextField获得的关键词进行判断给予相应结果查询
|
职位信息维护
数据库表
# 职位表 CREATE TABLE job( job_id VARCHAR(10) PRIMARY KEY, job_title VARCHAR(40), job_comm VARCHAR(255), dept_id VARCHAR(10), FOREIGN KEY(dept_id) REFERENCES dept(dept_id) # 外键约束 ); |
绘制界面
显示界面(在MainController中添加一下方法,用于显示职位信息界面)
@FXML JobController jobController = fxmlLoader.getController(); } catch (IOException e){
|
编写控制器
JobController控制器
/** @FXML private JobDao jobDao = new JobDaoImpl(); public void setPrimaryStage(Stage primaryStage) { @FXML //查询数据并添加到dataList中去
/** JobEditDialogController controller = fxmlLoader.getController(); stage.showAndWait(); /** JobEditDialogController controller = fxmlLoader.getController(); stage.showAndWait(); } catch (IOException e){
} else { /** //数据库删除 DialogUtil.showWarnDialog(this.primaryStage, “操作提示”, “删除成功!”); /** |
JobEditDialogController
控制器
public class JobEditDialogController { @FXML private JobDao jobDao; public void setJob(Job job) { jobIdTF.setEditable(false); //设置职位编号不可修改 } public void setStage(Stage stage) { public void setDataList(ObservableList dataList) { public void setJobDao(JobDao jobDao) { @FXML //调用Dao //修改数据库中数据 } //关闭对话框 @FXML
|
实体类Job
public class Job { private StringProperty jobId; //职位编号 public Job(){ public StringProperty jobIdProperty(){ public StringProperty jobTitleProperty(){ public StringProperty jobCommProperty(){ public StringProperty deptIdProperty(){
public String getJobId() { public void setJobId(String jobId) { public String getJobTitle() { public void setJobTitle(String jobTitle) { public String getJobComm() { public void setJobComm(String jobComm) { public String getDeptId() { public void setDeptId(String deptId) { @Override
|
数据访问层Dao
接口
public class JobDaoImpl implements JobDao { @Override @Override @Override @Override |
实现类
public class JobDaoImpl implements JobDao { @Override @Override @Override
|
实现新建职位功能
第一步:绘制界面并实现
显示对话框
@FXML
stage.showAndWait();
|
第二步:逻辑实现(控制器、Dao)
控制器
public class JobEditDialogController { @FXML private JobDao jobDao; public void setStage(Stage stage) { public void setDataList(ObservableList dataList) { public void setJobDao(JobDao jobDao) { @FXML //调用Dao //关闭对话框 @FXML
|
Dao
@Override
|
员工信息维护
绘制界面
显示页面
@FXML EmpController controller = fxmlLoader.getController();
} catch (IOException e){
|
数据库表
#员工表 CREATE TABLE emp( emp_id VARCHAR(10) PRIMARY KEY, emp_name VARCHAR(20), dept_id VARCHAR(10), job_id VARCHAR(10), email VARCHAR(60), FOREIGN KEY (dept_id) REFERENCES dept(dept_id), FOREIGN KEY (job_id) REFERENCES job(job_id) ); |
编写控制器
Emp
Controller
控制器
public class EmpController { @FXML private TableColumn<Emp,String> empIdColumn; @FXML private TableColumn<Emp,String> deptColumn; @FXML private TableColumn<Emp,String> empNameColumn; @FXML private ChoiceBox<String> conditionCB; @FXML private TableColumn<Emp,String> jobColumn; @FXML private HBox keywordTF; @FXML private TableView<Emp> empTableView; @FXML private TableColumn<Emp,String> emailColumn;
private ObservableList dataList= FXCollections.observableArrayList();
private EmpDao empDao=new EmpDaoImpl(); private Stage primaryStage;
public void setPrimaryStage(Stage primaryStage) { this.primaryStage = primaryStage; }
@FXML
void initialize(){ //绑定 empIdColumn.setCellValueFactory(new PropertyValueFactory<>(“empId”)); empNameColumn.setCellValueFactory(new PropertyValueFactory<>(“empName”)); emailColumn.setCellValueFactory(new PropertyValueFactory<>(“email”)); //准备要显示的数据 List<Emp> empList=empDao.queryAll(); dataList.addAll(empList); empTableView.setItems(dataList); }
@FXML
void onNewEmp(ActionEvent event) { FXMLLoader fxmlLoader=new FXMLLoader(); fxmlLoader.setLocation(EmpController.class.getResource(“/com/neuedu/neuedusystem/EmpEditDialogView.fxml”));
try { AnchorPane pane = fxmlLoader.load(); //创建场景 Scene scene=new Scene(pane); //创建舞台 Stage stage=new Stage(); stage.setScene(scene); stage.setTitle(“员工登录”); stage.initOwner(this.primaryStage); stage.initModality(Modality.WINDOW_MODAL);
EmpEditDialogController controller = fxmlLoader.getController(); controller.setDataList(dataList); controller.setStage(stage);
stage.showAndWait();
}catch (IOException e){ e.printStackTrace(); } }
@FXML
void onDelEmp(ActionEvent event) { DialogUtil.showWarnDialog(primaryStage,”删除提示”,”你确定要删除吗?”); Emp selectedEmp = empTableView.getSelectionModel().getSelectedItem();
if(selectedEmp!=null){ empDao.deleteEmp(selectedEmp.getEmpId()); dataList.remove(selectedEmp);
}else { DialogUtil.showWarnDialog(primaryStage,”数据错误”,”请选择要删除的数据”); } }
@FXML
void onUpdateEmp(ActionEvent event) { //更新员工 Emp selectedEmp = empTableView.getSelectionModel().getSelectedItem();
if(selectedEmp!=null) { FXMLLoader fxmlLoader = new FXMLLoader(); fxmlLoader.setLocation(EmpController.class.getResource(“/com/neuedu/neuedusystem/EmpEditDialogView.fxml”));
try { AnchorPane pane = fxmlLoader.load(); //创建场景 Scene scene = new Scene(pane); //创建舞台 Stage stage = new Stage(); stage.setScene(scene); stage.setTitle(“更新员工”); stage.initOwner(this.primaryStage); stage.initModality(Modality.WINDOW_MODAL);
EmpEditDialogController controller = fxmlLoader.getController(); controller.setStage(stage); controller.setEmp(selectedEmp);
stage.showAndWait();
} catch (IOException e) { e.printStackTrace(); }
}else { DialogUtil.showWarnDialog(primaryStage,”数据错误”,”请选择要更新的员工信息”); } }
@FXML
void onFindEmp(ActionEvent event) { //获取搜索的关键词 String keyword = empTF.getText(); if(keyword!=null &&!keyword.equals(“”)){//当它不是空字符串的时候 Emp emp = EmpDao.queryByName(keyword); if(emp!=null){//找得到 dataList.clear();//清空数据集 dataList.add(emp);//添加搜索的结果 }else{//找不到,查询为空 DialogUtil.showWarnDialog(this.primaryStage,”查询结果”,”请重新输入搜索词”); }
}else { //提示 // Alert alert=new Alert(Alert.AlertType.WARNING); // alert.initOwner(this.primaryStage); // alert.setTitle(“缺少关键词”); // alert.setContentText(“请再输入框中输入要搜索的关键词”); // alert.showAndWait();
DialogUtil.showWarnDialog(this.primaryStage,”缺少关键词”,”请再输入框中输入要搜索的关键词”); } } |
实体类Emp
//员工信息
public class Emp { private StringProperty empId; private StringProperty empName; private StringProperty deptId; private StringProperty jobId; private StringProperty email;
public Emp(){ empId=new SimpleStringProperty(“”); empName=new SimpleStringProperty(“”); deptId=new SimpleStringProperty(“”); jobId=new SimpleStringProperty(“”); email=new SimpleStringProperty(“”); }
public StringProperty empIdProperty(){ return empId; }
public StringProperty empNameProperty(){ return empName; }
public StringProperty deptIdProperty(){ return deptId; }
public StringProperty jobIdProperty(){ return jobId; }
public StringProperty emailProperty(){ return email; }
public String getEmpId() { return empId.get(); }
public void setEmpId(String empId) { this.empId.set(empId); }
public String getEmpName() { return empName.get(); }
public void setEmpName(String empName) { this.empName.set(empName); }
public String getDeptId() { return deptId.get(); }
public void setDeptId(String deptId) { this.deptId.set(deptId); }
public String getJobId() { return jobId.get(); }
public void setJobId(String jobId) { this.jobId.set(jobId); }
public String getEmail() { return email.get(); }
public void setEmail(String email) { this.email.set(email); }
@Override
public String toString() { return “Emp{” + “empId=” + empId + “, empName=” + empName + “, deptId=” + deptId + “, jobId=” + jobId + “, email=” + email + ‘}’; } } |
数据访问层Dao
接口
//员工表的增删改查
public interface EmpDao { /** * 根据员工Id查询员工姓名 * @param empId * @return */ String getEmpName(String empId);
/** * 用于查询所有员工的信息 * @return */ List<Emp> queryAll();
/** * 根据员工编号查询员工信息 * @param empId * @return */ Emp queryByName(String empName);
/** * 保存员工信息 * @param emp * @return */ boolean saveEmp(Emp emp);
/** * 更新员工信息 * @param emp * @return */ boolean updateEmp(Emp emp);
/** * 根据员工的编号 删除员工信息 * @param empId * @return */ boolean deleteEmp(String empId); }
|
实现类
public class EmpDaoImpl implements EmpDao { @Override
public String getEmpName(String empId) {
String sql=”select emp_name from emp where emp_id=”+empId;
try{ Connection connection = JdbcUtil.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); resultSet.next();//指向数据所在的行 String empName=resultSet.getString(“emp_name”); return empName;
}catch (SQLException e){ e.printStackTrace(); } return null; }
@Override
public List<Emp> queryAll() { String sql=”select*from emp”;
try { Connection connection = JdbcUtil.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet=statement.executeQuery(sql); List<Emp> empList=new ArrayList<>();
while(resultSet.next()){ Emp emp=new Emp(); emp.setEmpId(resultSet.getString(“emp_id”)); emp.setEmpName(resultSet.getString(“emp_name”)); emp.setEmail(resultSet.getString(“email”));
empList.add(emp); } JdbcUtil.close(connection,statement,resultSet); return empList;
}catch (SQLException e){ e.printStackTrace(); } return null; }
@Override
public Emp queryByName(String empName) { //String sql=”select*from job where job_title=?”; //改成一种模糊查询(大概) String sql=”select*from emp where emp_name like ‘%”+name+”%'”;//like可以添加%(没数量限制)和_(一个代表一个数) //System.out.println(sql); //System.out.println(sql);
try{ Connection connection = JdbcUtil.getConnection(); PreparedStatement statement = connection.prepareStatement(sql); //statement.setString(1,name); ResultSet resultSet = statement.executeQuery();
if(resultSet.next()){ Emp emp=new Emp(); Emp.setJobId(resultSet.getString(“emp_id”)); Emp.setJobTitle(resultSet.getString(“emp_name”)); Emp.setJobComm(resultSet.getString(“email”)); Emp.setDeptId(resultSet.getString(“dept_id”)); Emp.setDeptId(resultSet.getString(“job_id”)); //关闭资源 JdbcUtil.close(connection,statement,resultSet);//如果有数据就在这关闭数据,如果没数据就在下面关闭数据 return Emp; return null; }
@Override
public boolean saveEmp(Emp emp) { String sql=”insert into emp(emp_id,emp_name,email) values(?,?,?)”;
try { Connection connection = JdbcUtil.getConnection(); PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1,emp.getEmpId()); ps.setString(2,emp.getEmpName()); ps.setString(3,emp.getEmail()); boolean execute = ps.execute(); JdbcUtil.close(connection,ps,null); return execute;
}catch (SQLException e){ e.printStackTrace(); }
return false; }
@Override
public boolean updateEmp(Emp emp) { String sql=”update emp set emp_name=?,email=? where emp_id=?”;
try { Connection connection = JdbcUtil.getConnection(); PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1,emp.getEmpName()); ps.setString(2,emp.getEmail()); ps.setString(3,emp.getEmpId()); boolean execute = ps.execute(); JdbcUtil.close(connection,ps,null); return execute;
}catch (SQLException e){ e.printStackTrace(); }
return false; }
@Override
public boolean deleteEmp(String empId) { String sql=”delete from emp where emp_id=?”;
try { Connection connection = JdbcUtil.getConnection(); PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1,empId); boolean execute = ps.execute(); JdbcUtil.close(connection,ps,null); return execute;
}catch (SQLException e){ e.printStackTrace(); } return false; } } |
|
实现新建职位功能
第一步:绘制界面并实现
显示对话框
第二步:逻辑实现(控制器、Dao)
Emp
EditDialogController
控制器
public class EmpEditDialogController { @FXML private TextField emailTF;
@FXML private TextField empIdTF;
@FXML private TextField empNameTF;
private EmpDao empDao=new EmpDaoImpl(); private ObservableList dataList; private Stage stage; private Emp emp;
public void setEmp(Emp emp) { this.emp = emp; //数据回显 empIdTF.setText(emp.getEmpId()); empNameTF.setText(emp.getEmpName()); emailTF.setText(emp.getEmail()); }
public void setStage(Stage stage) { this.stage = stage; }
public void setDataList(ObservableList dataList) { this.dataList = dataList; }
@FXML
void onSubmit(ActionEvent event) { //员工登记
if(emp==null) { String empId = empIdTF.getText(); String empName = empNameTF.getText(); String email = emailTF.getText();
Emp emp = new Emp(); emp.setEmpId(empId); emp.setEmpName(empName); emp.setEmail(email); //保存数据 empDao.saveEmp(emp); dataList.add(emp);
}else { //更新员工信息 String empId=empIdTF.getText(); String empName=empNameTF.getText(); String email=emailTF.getText(); this.emp.setEmpId(empId); this.emp.setEmpName(empName); this.emp.setEmail(email);
//更新数据库 empDao.updateEmp(this.emp); } stage.close(); }
@FXML
void onCancel(ActionEvent event) { stage.close(); } }
|
Dao
|
实现类
public class EmpFormDaoImpl implements EmpFormDao { @Override
public List<EmpForm> queryAll() { String sql = “SELECT emp.emp_id,dept_name,emp_name,fix_salary FROM emp LEFT JOIN dept ON emp.dept_id=dept.dept_id LEFT JOIN fixed_salary ON emp.emp_id=fixed_salary.emp_id”;
try { Connection connection = JdbcUtil.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); //创建一个集合,用于存储查询出来的结果 List<EmpForm> empFormList = new ArrayList<>();
while (resultSet.next()) { EmpForm empForm = new EmpForm(); empForm.setEmpId(resultSet.getString(“emp_id”)); empForm.setEmpName(resultSet.getString(“emp_name”)); empForm.setDeptName(resultSet.getString(“dept_name”)); empForm.setRealSalary(resultSet.getDouble(“fix_salary”)); empFormList.add(empForm); } JdbcUtil.close(connection, statement, resultSet); return empFormList;
} catch (SQLException e) { e.printStackTrace(); } return null; }
@Override
public List<EmpForm> queryByName(String empName) { String sql = “SELECT emp.emp_id,dept_name,emp_name,fix_salary FROM emp LEFT JOIN dept ON emp.dept_id=dept.dept_id LEFT JOIN fixed_salary ON emp.emp_id=fixed_salary.emp_id where emp_name like’%” + empName + “%'”; System.out.println(sql);
try { Connection connection = JdbcUtil.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql);
//创建一个集合,用于存储查询出来的结果 List<EmpForm> empFormList = new ArrayList<>();
while (resultSet.next()) { EmpForm empForm = new EmpForm(); empForm.setEmpId(resultSet.getString(“emp_id”)); empForm.setEmpName(resultSet.getString(“emp_name”)); empForm.setDeptName(resultSet.getString(“dept_name”)); empForm.setRealSalary(resultSet.getDouble(“fix_salary”)); empFormList.add(empForm); } JdbcUtil.close(connection, statement, resultSet);
if (empFormList.size() != 0) { return empFormList; }
} catch (SQLException e) { e.printStackTrace(); } return null; } }
|
第二阶段(工资数据维护):
-
固定工资维护
-
实现工资列表功能
第一步:绘制固定工资的页面
第二步:读取固定工资表,并显示在TableView中
FixedSalaryController
/** @FXML //dao //ObservableList /** }
@FXML } @FXML }
|
FixedSalaryDao
/** /** /** /** /** /** }
|
FixedSalaryDaoImpl
/**
@Override @Override @Override //关闭资源 @Override @Override
|
第三步:显示固定工资维护的页面
@FXML FixedSalaryController deptController = fxmlLoader.getController(); } catch (IOException e){ |
-
更新工资项
第一步: 绘制编辑界面
第二步:弹出窗体
@FXML FixedSalaryController fixedSalaryController = fxmlLoader.getController(); } catch (IOException e){
|
第三步:编写
FixedSalaryEditController
/** @FXML private FixedSalary fixedSalary; public void setFixedSalaryDao(FixedSalaryDao fixedSalaryDao) { public void setStage(Stage mStage) { public void setFixedSalary(FixedSalary fixedSalary) {
@FXML } @FXML //调用dao更新数据库中的数据 mStage.close(); @FXML }
|
第四步:编写DAO层
/**
@Override @Override @Override //关闭资源 @Override @Override //根据fs_id获取emp_id //根据员工的id更新员工的姓名 //关闭资源
|
-
导入数据维护
-
创建表
# 考勤表 CREATE TABLE info( info_id INT(11) PRIMARY KEY AUTO_INCREMENT, sick_leave INT(6), absence_leave INT(6), late INT(6), leave_early INT(6), over_time INT(6),`neuedu_system“info` year_ VARCHAR(10), month_ VARCHAR(10), emp_id VARCHAR(10), FOREIGN KEY(emp_id) REFERENCES emp(emp_id) ) |
外键:
-
绘制界面
-
编写逻辑处理(控制器、实体类)
控制器
public class ImportInfoController { @FXML private Stage primaryStage; //主窗体 public void setPrimaryStage(Stage primaryStage) { @FXML @FXML @FXML
|
实体类
/** private IntegerProperty infoId; //通过构造函数对以上成员变量进行初始化 public IntegerProperty infoIdProperty(){ public IntegerProperty sickLeaveProperty(){ public IntegerProperty absenceLeaveProperty(){ public IntegerProperty lateProperty(){ public IntegerProperty leaveEarlyProperty(){ public IntegerProperty overTimeProperty(){ public StringProperty yearProperty(){ public StringProperty monthProperty(){ public StringProperty empIdProperty(){ public int getInfoId() { public void setInfoId(int infoId) { public int getSickLeave() { public void setSickLeave(int sickLeave) { public int getAbsenceLeave() { public void setAbsenceLeave(int absenceLeave) { public int getLate() { public void setLate(int late) { public int getLeaveEarly() { public void setLeaveEarly(int leaveEarly) { public int getOverTime() { public void setOverTime(int overTime) { public String getYear() { public void setYear(String year) { public String getMonth() { public void setMonth(String month) { public String getEmpId() { public void setEmpId(String empId) { @Override
|
-
Dao层
public class ImportInfoDaoImpl implements ImportInfoDao { @Override @Override @Override @Override
|
-
实现数据导入功能
需要使用的jar包,POI相关的jar,它是用于操作office办公软件的,我们该功能需要利用它去读取Excel文件。
第一步:引入jar包
<dependency> |
第二步:读取Excel
FileChooser fileChooser = new FileChooser(); XSSFWorkbook workbook = new XSSFWorkbook(fis);
|
查询员工的姓名
@Override
|
添加数据的过程中做去重处理
/** for (int i = 0; i < size; i++) {
|
依据数据中的数据刷新TableView
/**
|
-
编辑数据
第一步:绘制界面
第二步:编写controller
显示对话框
@FXML //操作Controller stage.showAndWait(); } catch (IOException e){
|
对话框控制器
@FXML private ImportInfo importInfo; public void setDataList(ObservableList dataList) { public void setImportInfoDao(ImportInfoDao importInfoDao) { public void setStage(Stage stage) { @FXML public void setImportInfo(ImportInfo importInfo) { @FXML //调用Dao更新考勤数据 @FXML
|
-
工资计算
-
创建数据库表
# 实际工资表 CREATE TABLE real_salary(
rs_id INT(11) PRIMARY KEY AUTO_INCREMENT, income DOUBLE(20,2), fs_id INT(11), emp_id VARCHAR(10), sick_cut DOUBLE(18, 2), absence_cut DOUBLE(18,2), late_cut DOUBLE(18,2), leave_early_cut DOUBLE(18,2), overtime_pay DOUBLE(18,2),`real_salary` reserve DOUBLE(18,2), old_assurece DOUBLE(18,2), medical_assurece DOUBLE(18,2), fire_assurece DOUBLE(18,2), tax DOUBLE(18,2), FOREIGN KEY(fs_id) REFERENCES fixed_salary(fs_id), FOREIGN KEY(emp_id) REFERENCES emp(emp_id) ) |
-
绘制界面并显示
@FXML SalaryDealController salaryDealController = fxmlLoader.getController(); } catch (IOException e){
|
-
编写控制器
SalaryDealController
/** @FXML private RealSalaryDao realSalaryDao = new RealSalaryDaoImpl(); @FXML empIdColumn.setCellValueFactory(new PropertyValueFactory<>(“empId”)); List<RealSalary> realSalaryList = realSalaryDao.queryAll(); @FXML } @FXML } @FXML } @FXML }
|
封装实体类RealSalary
/** private IntegerProperty rsId; public RealSalary(){ public DoubleProperty busSubsidyProperty(){ public double getBusSubsidy() { public void setBusSubsidy(double busSubsidy) { public DoubleProperty foodSubsidyProperty(){ public double getFoodSubsidy() { public void setFoodSubsidy(double foodSubsidy) { public DoubleProperty baseSalaryProperty(){ public DoubleProperty incomeProperty(){ public StringProperty empNameProperty(){ public DoubleProperty sickCutProperty(){ public DoubleProperty leaveEarlyCutProperty(){ public DoubleProperty reserveProperty(){ public DoubleProperty medicalAssureceProperty(){ public DoubleProperty taxProperty(){
public int getRsId() { public IntegerProperty rsIdProperty() { public void setRsId(int rsId) { public double getIncome() { public void setIncome(double income) { public int getFsId() { public IntegerProperty fsIdProperty() { public void setFsId(int fsId) { public FixedSalary getFixedSalary() { public ObjectProperty<FixedSalary> fixedSalaryProperty() { public void setFixedSalary(FixedSalary fixedSalary) { public String getEmpId() { public StringProperty empIdProperty() { public void setEmpId(String empId) { public Emp getEmp() { public ObjectProperty<Emp> empProperty() { public void setEmp(Emp emp) { public String getEmpName() { public void setEmpName(String empName) { public double getSickCut() { public void setSickCut(double sickCut) { public double getAbsenceCut() { public void setAbsenceCut(double absenceCut) { public double getLateCut() { public void setLateCut(double lateCut) { public double getLeaveEarlyCut() { public void setLeaveEarlyCut(double leaveEarlyCut) { public double getOvertimePay() { public void setOvertimePay(double overtimePay) { public double getReserve() { public void setReserve(double reserve) { public double getOldAssurece() { public void setOldAssurece(double oldAssurece) { public double getMedicalAssurece() { public void setMedicalAssurece(double medicalAssurece) { public double getFireAssurece() { public void setFireAssurece(double fireAssurece) { public double getTax() { public void setTax(double tax) { public double getBaseSalary() { public void setBaseSalary(double baseSalary) { @Override
|
-
编写实际工资的数据访问层Dao
public class RealSalaryDaoImpl implements RealSalaryDao { @Override //查询员工信息 //考勤信息 //社保信息 //税 |
-
计算工资
在
RealSalary
类中实现计算方法
//计算考勤(迟到、早退、事假、病假、加班) //计算考勤 //第一步:查出该员工的考勤信息 //刚刚同学 this.setSickCut(daySalary * sickLeave * 0.5); //计算社保 //养老保险 30000 0.07 return this.reserve.get() + this.oldAssurece.get() + this.medicalAssurece.get()+this.fireAssurece.get();
//baseSalary – 考勤 + 加班 – 公积金 – 社保 – 5000 this.setTax(tax_); //计算实际收入 income
|
第三阶段(报表管理):
-
员工工资统计报表界面的绘制
第一步:绘制界面内容
其中用了Tableview控件,SplitePane用于把页面划分出上下两部分, HBox水平摆放控件。
Button控件、Label控件、ChoiceBox控件。
其中表格中的表头信息有:部门名称、部门编号、员工姓名、实发工资
第二步:显示部门页面
在MainController中传入mainView对象,用于切换主页面中的布局内容
private BorderPane mainView; public void setMainView(BorderPane mainView) {
|
在MainApp中获取MainController,把mainView传递过去
完成显示部门页面的逻辑
ExportEmpFormController controller = fxmlLoader.getController(); } catch (IOException e){
|
效果图如下:
-
员工工资统计报表中的内容
第一步:
编写控制器ExportEmpFormController
public class ExportEmpFormController { @FXML @FXML @FXML @FXML public void setPrimaryStage(Stage primaryStage) { @FXML //查询数据库,加载报表数据,sql语句怎么写? @FXML @FXML // XSSFCell cell2 = headerRow.createCell(1); for (int i = 0; i < dataList.size(); i++) {
|
创建实体类EmpForm
public EmpForm(){ //双向绑定 public String getDeptName() { public void setDeptName(String deptName) { public String getEmpId() { public void setEmpId(String empId) { public String getEmpName() { public void setEmpName(String empName) { public double getRealSalary() { public void setRealSalary(double realSalary) { @Override
|
编写Dao及其实现类
|
编写实现类EmpFormDaoImpl
@Override //创建一个集合,用于存储查询出来的结果 |
测试:
-
显示数据,如图所示:
-
通过员工姓名查询员工信息报表
(
1)
如果输入为空,则会弹出警告,如图所示:
(
2)
如果输入的员工姓名不存在,则会弹出警告,如图所示:
(
3)
假设输入“王”字,那么员工姓名中含有“王”字的员工报表会查询出来,如图所示:
导出数据到excel中
定义文件路径,没导出数据前,文件为空,如图所示:
点击“导出”,在文件夹中会自动生成一个excel文件,里面有我们导出的数据,如图所示:
五、实验结果及分析(遇到的问题与解决)
问题
:在Idea中,与数据库数据绑定时,出现表中列名拼写错误错误,无法匹配并绑定。
解决
:同步改正Idea与数据库中列名。
问题
:反射异常。
解决
:未将libs中的jar包导入到Libraries中。
问题
:fxml.LoadException;
解决
:用try-catch()抛出异常即可。
问题
:未定义List列表集合;
解决
:在实现类中,添加<List>。
-
问题
:Object未经过初始化;
解决
:对Object进行初始化处理。
-
问题
:Java找不到模块:javafx.controls
解决
:百度文件路径尝试使用建议的模式进行编译:javac –module-path $ PATH_TO_FX –add-modules javafx.controls HelloFX.java
六、实验体会
在这次的学习中,学习并掌握Java开发运行、JavaFX、数据库的链接与应用。从讲解Java、数据库的基础知识,到灵活运用。本次短实习锻炼我们的编程能力,培养我们的开发能力。我们的团队合作能力得到了加强,通过这个项目,我们对Java开发和数据库的联系认知也更加深刻性。同时感谢指导老师和助教老师在学习和生活中对我们的教导和帮助。