一个简单的实习生管理系统

写了一个简单的实习生管理系统,用于自己复习java后端。由于是复习java为目的,故而这个系统没有用框架,control层基本手写servlet完成。基本的增删改查,级联删除功能均有实现。适合java刚入门的同学阅读,大神们请别见笑,如有错误欢迎指出。

文章目录

      • 一、系统简介:
      • 二、系统功能简介:
      • 三、项目源码及大致实现思路:
        • 1、BaseServlet
        • 2、JDBCUtils
        • 3、大致说明:
        • 4、项目分享:

一、系统简介:

1、MVC三层架构
2、control层手写servlet实现(封装BaseServlet)
3、MySQL数据库
4、前端框架miniui

二、系统功能简介:

1、有人员信息和考核信息两个界面
2、两个页面均能实现对应信息的增删改查,并且当删除某个人的信息时,自动删除这个人所有的考核信息。
3、人员的学号根据日期自动生成
4、新增信息对应的表单校验

前端是由框架实现,我写改项目时又以复习java为目的,故文中不会花篇幅介绍前端页面,感兴趣的同学可以去miniui官网查看其api文档。本文主要记录后端的实现即思路。

MVC三层架构,老生常谈的问题了。视图层View,与用户的交互及各个表单传参;模型层Model,模型负责各个功能的实现(如登录、增加、删除功能)。模型用JavaBean实现;控制层Controller,控制层负责将视图与模型一一对应起来。相当于一个模型分发器。

三、项目源码及大致实现思路:

1、BaseServlet

手动封装BaseServlet的目的是为了实现,在前端Ajax请求数据时能通过配置的web.xml和方法名请求到对应的control层方法,如:

			$.ajax({
				url : "trainee.do?method=saveTrainee",
				type : 'post',
				data : {
					data : json
				},
				cache : false,
				success : function(text) {
					CloseWindow("save");
				},
				error : function(jqXHR, textStatus, errorThrown) {
					alert(jqXHR.responseText);
					CloseWindow();
				}
			});

通过封装BaseServlet和配置web.xml后,该Ajax请求将会从TraineeInfoServlet中的saveTrainee方法中请求数据。
BaseServlet的代码如下:

package com.epoint.action;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BaseServlet extends HttpServlet {

    //通用的servlet方法
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //对于以后的所有方法同一的做请求响应乱码处理
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        //获取用户请求的方法
        String methodName = request.getParameter("method");

        //判断方法名是否为空 ""    null
        if (methodName.trim().isEmpty() || methodName == null) {
            throw new RuntimeException("你没有传递method参数!无法确定你要调用的方法!");
        }

        //1.    获取当前类的class对象
        Class c = this.getClass();

        //2.    通过当前类的class对象的getMethod()方法查找是否存在对应方法
        Method method = null;
        try {
            method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
        }
        catch (Exception e) {
            throw new RuntimeException("你要调用的方法!" + methodName + "不存在!");
        }

        //3. 通过反射动态的调用对应的方法
        try {
            //获取方法的返回值
            String result = (String) method.invoke(this, request, response);
            //判断是否有返回值   没有就什么都不做
            if (result == null || result.trim().isEmpty()) {
                return;
            }

            //查看返回值是否包含冒号,如果么有给用户抛异常
            //如果有,使用冒号进行分割  前半[转发或重定向的标识]与后半[跳转的地址]
            //做转发和重定向了
            if (result.contains(":")) {
                //拆分

                //获取冒号的位置
                int index = result.indexOf(":");
                //获取冒号之前的
                String s = result.substring(0, index);
                //获取冒号之后的
                String path = result.substring(index + 1);

                if (s.equalsIgnoreCase("c")) {
                    //重定向
                    response.sendRedirect(request.getContextPath() + path);
                }
                else if (s.equalsIgnoreCase("z")) {
                    //转发
                    request.getRequestDispatcher(path).forward(request, response);
                }
                else {
                    throw new RuntimeException("你指定的操作" + s + "当前版本不支持!");
                }
            }
            else {
                //没有冒号
                throw new RuntimeException("你指定跳转的URL存在问题!");
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("你要调用的方法!" + methodName + "内部存在问题!");
        }
    }

}

2、JDBCUtils

连接数据库的工具类,代码如下:

package com.epoint.utils;

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtils {

    // 配置文件的默认配置,必须给出c3p0-config.xml
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

    // 它是事务专用连接
    private static ThreadLocal tl = new ThreadLocal();

    /**
          * 使用连接池返回一个连接对象
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        Connection con = tl.get();
        // 当con不等于null,说明已经调用过beginTransaction(),表示开启了事务!
        if (con != null)
            return con;
        return dataSource.getConnection();
    }

    /**
          * 返回连接池对象!
     * @return
     */
    public static DataSource getDataSource() {
        return dataSource;
    }

    /**
          * 开启事务
     * 1. 获取一个Connection,设置它的setAutoComnmit(false)
     * 2. 还要保证dao中使用的连接是我们刚刚创建的!
     * ----------------
     * 1. 创建一个Connection,设置为手动提交
     * 2. 把这个Connection给dao用!
     * 3. 还要让commitTransaction或rollbackTransaction可以获取到!
     * @throws SQLException 
     */
    public static void beginTransaction() throws SQLException {
        Connection con = tl.get();
        if (con != null)
            throw new SQLException("已经开启了事务,请不要重复开启了!");
        /*
         * 1. 给con赋值!
         * 2. 给con设置为手动提交!
         */
        con = getConnection();//给con赋值,表示事务已经开始了
        con.setAutoCommit(false);

        tl.set(con);//把当前线程的连接保存起来!
    }

    /**
          * 提交事务
     * 1. 获取beginTransaction提供的Connection,然后调用commit方法
     * @throws SQLException 
     */
    public static void commitTransaction() throws SQLException {
        Connection con = tl.get();//获取当前线程的专用连接
        if (con == null)
            throw new SQLException("还没有开启事务,不能提交!");
        /*
         * 1. 直接使用con.commit()
         */
        con.commit();
        con.close();
        // 把它设置为null,表示事务已经结束了!下次再去调用getConnection()返回的就不是con了
        tl.remove();//从tl中移除连接
    }

    /**
          * 提交事务
     * 1. 获取beginTransaction提供的Connection,然后调用rollback方法
     * @throws SQLException 
     */
    public static void rollbackTransaction() throws SQLException {
        Connection con = tl.get();
        if (con == null)
            throw new SQLException("还没有开启事务,不能回滚!");
        /*
         * 1. 直接使用con.rollback()
         */
        con.rollback();
        con.close();
        tl.remove();
    }

    /**
          * 释放连接 
     * @param connection
     * @throws SQLException 
     */
    public static void closeConnection(Connection conn) throws SQLException {
        Connection con = tl.get();
        /*
		  * 判断它是不是事务专用,如果是,就不关闭!
		  * 如果不是事务专用,那么就要关闭!
         */
        // 如果con == null,说明现在没有事务,那么connection一定不是事务专用的!
        if (con == null)
            conn.close();
        // 如果con != null,说明有事务,那么需要判断参数连接是否与con相等,若不等,说明参数连接不是事务专用连接
        if (con != conn)
            conn.close();
    }
}

3、大致说明:

比较费脑筋的就这两个了,其余就是建立对应实体类,在action中的servlet中完成数据交互需要的方法,根据需求完成对应的sql语句,一些工具类的调用等等。不做过多详述,如有需要可以下载笔者项目源码,如有不对的地方,请大家指出。

4、项目分享:

网盘地址:https://pan.baidu.com/s/1YiIX52tvAsrM8knI4j0grw
提取码:7tdj

你可能感兴趣的:(后端)