企业日常事务管理系统
一、系统分析
1.1、需求
在员工不访问外网的情况下,进行发布消息、查看消息、回复消息和批复消息;
1.2、功能
- 用户进行登陆及注销;
- 普通员工可以发布、查看、回复消息;
- 管理层领导可以发布、查看、回复和批复消息;
二、系统设计
2.1、系统流程
2.2、技术栈
- MVC架构:JavaBean+JSP+Servlet;
- 开发工具:IDEA+Maven+SQLyog;
- web服务器:Tomcat9.0;
2.3、工程结构
三、模块实现
3.1、数据库模块
3.1.1、数据库设计
数据库db_affairmanage共有四张表:
- 员工表tb_employee:记录了ID、姓名、性别、生日、手机号、属地、加入时间、密码、领导标签;
- 消息表tb_message:记录了ID、题目、内容、发布者ID、发布时间;
- 回复表tb_reply:记录了ID、内容、回复者ID、回复时间、对应消息ID;
- 批复表tb_criticism:记录了ID、内容、批复者ID、批复时间、对应消息ID;
关系E-R表如下:
3.1.2、ORM表-类映射
编写每张表的对应java类,即Bean类,只包含了getter()和setter();
3.1.3、配置连接文件
设置数据连接时使用的驱动、url(指定数据库和参数)、用户和密码;
3.1.3、公共类设计
DBConnection: 实现基本共用的数据库连接、查询、更新等操作;它是一个静态类,包含五个静态方法:
- 初始化:从配置文件加载数据库信息;
public static void init(){
Properties params = new Properties();
String configFile = "db.properties";
//使用类加载器加载配置文件
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream(configFile);
try{
params.load(is);
}catch(IOException e){
e.printStackTrace();
}
driver = params.getProperty("driver");
url = params.getProperty("url");
user = params.getProperty("user");
password = params.getProperty("password");
}
- 返回连接;
public static Connection getConnection(){
Connection connection = null;
try{
Class.forName(driver);
connection = DriverManager.getConnection(url,user,password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
- 查询操作;
public static ResultSet execute(Connection connection, PreparedStatement pstm,ResultSet rs,String sql, Object[] params) throws Exception{
pstm = connection.prepareStatement(sql);
for(int i=0; i<params.length; i++){
pstm.setObject(i+1, params[i]);
}
rs = pstm.executeQuery();
return rs;
}
- 更新操作;
//更新操作
public static int execute(Connection connection, PreparedStatement pstm, String sql,Object[] params) throws Exception {
int updateRows = 0;
pstm = connection.prepareStatement(sql);
for(int i=0; i<params.length; i++){
pstm.setObject(i+1, params[i]);
}
updateRows = pstm.executeUpdate();
return updateRows;
}
- 关闭资源;
public static boolean closeResource(Connection connection,PreparedStatement pstm, ResultSet rs){
boolean flag = true;
if(rs != null){
try{
rs.close();
rs =null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if(pstm != null){
try{
pstm.close();
pstm =null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
if(connection != null){
try{
connection.close();
connection =null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
return flag;
}
3.2、员工识别模块
3.2.1、显示层jsp
<form action="login.do" method="post">
<p>员工编号:<input type="text" name="employeeName" value="${param.employeeName}"/></p>
<p> </p>
<p>系统口令:<input type="password" name="password" /></p>
<p> </p>
<p><input type="submit" value="提交" />
<input type="reset" value="重置" /></p>
</form>
3.2.2、DAO层
Dao层操纵实体类Bean的增删改查CRUD,调用数据库的公共类DBConnection,封装JDBC操作,与数据库进行交互;
- 接口EmployeeDao:
定义对Bean类的增删改查等方法接口;
public interface EmployeeDao {
//增删改查CRUD
void addEmployee(Connection connection, Employee employee);
void deleteEmployee(Connection connection, int employeeID);
int updateEmployee(Connection connection,Employee employee);
List<Employee> findAllEmployee(Connection connection);
Employee finEmployeeByID(Connection connection,int employeeID);
}
- 具体类EmployeeDaoImpl:
使用数据库公共类DBConnection,实现接口中对Bean类的增删改查等方法接口,封装对Bean类的JDBC操作;
public void addEmployee(Connection connection, Employee employee){
//声明预处理对象
PreparedStatement pstm = null;
//查询语句
String sql = "INSERT INTO tb_employee VALUES (?,?,?,?,?,?,?,?,?)";
//设置语句属性
Object[] params = {employee.getEmployeeID(),employee.getEmployeeName(),employee.isEmployeeSex(),employee.getEmployeeBirth(),employee.getEmployeePhone(),employee.getEmployeePlace(),employee.getJoinTime(),employee.getPassword(),employee.isLead()};
//尝试执行
try{
//启动更新
DBConnection.execute(connection,pstm,sql,params);
}catch (Exception e) {
e.printStackTrace();
}
//最终都要关闭资源
finally {
DBConnection.closeResource(null,pstm,null);
}
}
- 工厂类EmployeeDaoFactory:
静态类,根据需求选择返回合适的具体实现类;
public class EmployeeDaoFactory {
public static EmployeeDao getEmployeeDaoInstance(){
return (EmployeeDao) new EmployeeDaoImpl();
}
}
3.2.3、业务层service
业务层的主要工作是接收具体业务请求,调用DAO层完成与数据库的交互;特点是只处理对应业务;
- 接口EmployeeService:
定义Employee相关的服务方法;
Employee getEmployee(int employeeID);//通过ID获取员工信息
Employee getEmployee(String employeeName,String password);//通过名字密码获取员工信息
- 具体类EmployeeServiceImpl:
实现接口中的服务;
@Override
private EmployeeDao employeeDao;
public EmployeeServiceImpl() {
employeeDao = EmployeeDaoFactory.getEmployeeDaoInstance();
}
@Override
public Employee getEmployeeByID(int employeeID){
Connection connection = null;
Employee employee = null;
//通过工厂类获取具体DAO操作Employee类
try {
connection = DBConnection.getConnection();
employee = employeeDao.findEmployeeByID(connection,employeeID);
} catch (Exception e) {
e.printStackTrace();
}finally {
DBConnection.closeResource(connection,null,null);
}
return employee;
}
3.2.4、控制层servlet
控制层的主要工作是处理用户参数、调用业务层、建立与销毁数据库连接、转发与重定向视图等;
- 编写LoginServlet:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.处理请求参数
String employeeName = req.getParameter("employeeName");
String password = req.getParameter("password");
//2.调用业务层,匹配用户
EmployeeService employeeService = new EmployeeServiceImpl();
Employee employee = employeeService.getEmployee(employeeName,password);
if(employee != null){//匹配成功
//设置session
req.getSession().setAttribute("employee",employee);
//重定向
resp.sendRedirect("/jsp/index.jsp");
}else{//匹配失败
req.setAttribute("error","密码或用户名不对");
//转发
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
- 注册Servlet:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.zhu2change.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
3.2.5 过滤器Filter:
编写好Filter,并配置对哪个web资源进行拦截后,Web服务器每次在调用web资源的service方法之前(这里指执行该Servlet之前),都会先调用一下filter的doFilter方法;
过滤器是针对一次HTTP请求的,不属于具体的MVC层;
- 登陆过滤器LoginFilter:
将未登陆的连接重定向错误处理页面;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1.转换成http
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse reps = (HttpServletResponse) servletResponse;
//2.检验是否登陆
Employee employee = (Employee) req.getSession().getAttribute("employee");
if(employee == null){//未登陆
reps.sendRedirect("jsp/error.jsp");
}else{
//通过过滤,允许访问资源
filterChain.doFilter(req,reps);
}
}
@Override
public void destroy() {
}
- 系统过滤器SysFilter:
设置响应和请求的编码方式;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//转换成http
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse reps = (HttpServletResponse) servletResponse;
//设置编码
req.setCharacterEncoding("utf-8");
reps.setCharacterEncoding("utf-8");
reps.setHeader("Content-Type","text/html;charset=utf-8");
filterChain.doFilter(req,reps);
}
- 配置使用:
对/jsp/下的所有页面使用登陆过滤器;
系统过滤器适用所有页面;
<!--登陆过滤器-->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.zhu2change.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>
<!-- 系统过滤器-->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.zhu2change.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>