JavaWeb学生管理系统(详细源码+解析)


很多人大学的第一个小项目就是使用JavaWeb实现了一个学生管理系统或者是图书管理系统。在没有项目经验的情况下,前后端都需要自己去完成,还是要耗费不少时间精力的。本次我就分享一下我在大学期间完成的第一个小项目:学生管理系统。采用的技术有:Thymeleaf+Ajax+HTML+JQuery+Java+MySQL。下面会进行详细介绍,也可以关注微信公众号【橙晴丰Ciao】,私信我获取项目源码:JavaWeb学生管理系统。

效果演示

在这里插入图片描述
如何实现上面图片所实现的效果呢?接下来我将进行一个简单介绍。

项目搭建

  • 安装好Java环境【验证方式:同时点击win+r输入java -version】
  • 安装好MySQL环境
  • 先→创建一个JavaWeb项目,然后再实现具体的功能。

项目结构

JavaWeb项目搭建好后,就可以进行开发了,为了让第一次学习的小伙伴更加清楚地知道项目结构,我先把开发好后的结构图展示一下:
在这里插入图片描述

数据库搭建

在MySQL数据库中创建一个student_info数据库,用于存储我们要操作的学生信息表以及管理员登录表。

CREATE DATABASE student_info;

DROP TABLE IF EXISTS `t_login`;
CREATE TABLE `t_login` (
  `user_id` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `user_password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

-- ----------------------------
-- Table structure for `t_student`
-- ----------------------------
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
  `student_id` int(11) NOT NULL AUTO_INCREMENT,
  `student_name` varchar(100) DEFAULT NULL,
  `student_class` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`student_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1704134100 DEFAULT CHARSET=utf8;

项目开发

项目对数据库的操作是必不可少的,所以我们先进行数据库方面的配置。在resource文件夹中进行数据库连接方面的配置:

常用配置

druid.properties

数据库可能存在时区问题,根据报错提示网上查找解决方案修改url即可

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/student_info?  
username=root
password=root
initialSize=5
maxActive=10
maxWait=1000

JDBCUtil

src/utils工具包中创建JDBCUtil工具类进行数据库连接等操作:

package com.lzk.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtil {
    private static DataSource dataSource;
    static {
        try {
            //读取配置文件,创建连接池
            InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties properties = new Properties();
            properties.load(inputStream);

            //使用DruidDataSourceFactory创建连接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接池
     * @return
     */
    public static DataSource getDataSource(){
        return dataSource;
    }

    /**
     * 获取连接
     * @return
     */
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 归还连接的方法
     * @param connection
     */
    public static void releaseConnection(Connection connection){
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }
}

BaseDao

src/utils工具包中创建BaseDao工具类进行数据增删改查等操作:

package com.lzk.utils;


import com.lzk.utils.JDBCUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BaseDao<T> {
    private QueryRunner queryRunner = new QueryRunner();
    /**
     * 批处理方法
     * @param sql
     * @param paramArr
     * @return
     */
    public int[] batchUpdate(String sql,Object[][] paramArr){
        Connection conn = JDBCUtil.getConnection();
        try {
            return queryRunner.batch(conn,sql,paramArr);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            JDBCUtil.releaseConnection(conn);
        }
    }
    /**
     * 执行增删改的sql语句
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object... params){
        Connection conn = JDBCUtil.getConnection();
        //执行增删改的sql语句,返回受到影响的行数
        try {
            return queryRunner.update(conn,sql,params);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            JDBCUtil.releaseConnection(conn);
        }
    }
    /**
     * 执行查询一行数据的sql语句,将结果集封装到JavaBean对象中
     * @param clazz
     * @param sql
     * @param params
     * @return
     */
    public T getBean(Class<T> clazz,String sql,Object... params){
        Connection conn = JDBCUtil.getConnection();

        try {
            return queryRunner.query(conn,sql,new BeanHandler<>(clazz),params);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            JDBCUtil.releaseConnection(conn);
        }
    }
    /**
     * 执行查询多行数据的sql语句,并且将结果集封装到List<JavaBean>
     * @param clazz
     * @param sql
     * @param params
     * @return
     */
    public List<T> getBeanList(Class<T> clazz, String sql, Object... params){
        Connection conn = JDBCUtil.getConnection();
        try {
            return queryRunner.query(conn,sql,new BeanListHandler<>(clazz),params);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            JDBCUtil.releaseConnection(conn);
        }
    }
    //查询数据条数
    public long findCount(String sql, Object... params) throws SQLException {
        Connection conn = JDBCUtil.getConnection();
        try {
            long count= queryRunner.query(conn,sql,new ScalarHandler<>(),params);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            JDBCUtil.releaseConnection(conn);
        }
    }

}

数据模型层

User

用户实体类,跟数据库中的t_login表对应,存储管理员的信息。要有构造方法(无参、多参)以及getter和setter方法。

public class User {
    private String userId;
    private String userPassword;
}

Student

学生实体类,对应学生信息表。要有构造方法(无参、多参)以及getter和setter方法。

public class Student {
    private Integer studentId;
    private String studentName;
    private String studentClass;
}

PageInfo

分页信息实体类,不涉及数据库存储,只用于分页信息展示。要有构造方法(无参、多参)以及getter和setter方法。

public class PageInfo {

    //当前页 currentPage
    private Long currentPage;
    
    //页面大小
    private Long pageSize = 5L;

    //总数据totalCount
    private Long totalCount;

    //总页数totalPage
    private Long totalPage;
    
    //上一页
    private Long previousPage;
    
    //下一页
    private Long nextPage;
}

以上实体类都需要有getter和setter方法,否则在进行Thymeleaf模板渲染时就会出错。

web.xml配置文件

这个文件在web/WEB-INF,可以通过配置此文件进行控制层的映射。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <!-- 把首页指向portalServlet,表示请求路径为/时,交由portalServlet进行处理 -->
    <welcome-file-list>
        <welcome-file>portalServlet</welcome-file>
        <!-- 也可以通过这种方式配置首页,但login页面有使用thymeleaf语法,直接使用静态资源访问方式需要进行页面变量修改 -->
        <!--        <welcome-file>/WEB-INF/view/login.html</welcome-file>-->
    </welcome-file-list>
    <!-- 在上下文参数中配置视图前缀和视图后缀,这个是使用了Thymeleaf后需要进行配置的,
    表示经过servlet渲染后返回的页面的路径以及后缀 -->
    <context-param>
        <param-name>view-prefix</param-name>
        <param-value>/WEB-INF/view/</param-value>
    </context-param>
    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>
    <!-- 这个servlet由项目中哪个包下的servlet进行处理 -->
    <servlet>
        <servlet-name>PortalServlet</servlet-name>
        <servlet-class>com.lzk.servlet.model.PortalServlet</servlet-class>
    </servlet>
	<!-- 处理请求学生数据时路径的映射配置 -->
	 <servlet-mapping>
        <servlet-name>StudentServlet</servlet-name>
        <url-pattern>/student</url-pattern>
    </servlet-mapping>
	
    <servlet>
        <servlet-name>StudentServlet</servlet-name>
        <servlet-class>com.lzk.servlet.model.StudentServlet</servlet-class>
    </servlet>
	
    <servlet>
        <servlet-name>CodeServlet</servlet-name>
        <servlet-class>com.lzk.servlet.model.CodeServlet</servlet-class>
    </servlet>
     <servlet-mapping>
        <servlet-name>CodeServlet</servlet-name>
        <url-pattern>/code</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>PortalServlet</servlet-name>
        <url-pattern>/portalServlet</url-pattern>
    </servlet-mapping>
</web-app>

经过上面的配置后,当访问首页/时,就会交由portalServlet进行处理。

ProtalServlet

package com.lzk.servlet.model;

import com.lzk.servlet.base.ViewBaseServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class PortalServlet extends ViewBaseServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解析模板
        processTemplate("login", request, response);
    }
}

protalServlet进行请求处理时会将login页面进行渲染后返回,之所以可以实现模板渲染,是因为继承了ViewBaseServlet类。

ViewBaseServlet

这个类是基于Thymeleaf实现的可以进行模板渲染,继承自该类的所有子实现类也具有相同的功能。

package com.lzk.servlet.base;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {

        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);

        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // ②设置前缀
        String viewPrefix = servletContext.getInitParameter("view-prefix");

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);

    }

    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

login页面

在ProtalServlet中会进行模板渲染login页面,也就是登录时候的界面。因为我们在web.xml中进行了模板渲染视图上下文配置,所以该页面需要在/WEB-INF/view/中,并且为html形式。

这个页面就是一个登录表单,就是样式比较多

<!doctype html>
<html lang="zh-CN" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/favicon.ico">
    <link rel="canonical" href="https://getbootstrap.com/docs/3.4/examples/signin/">

    <title>学生管理系统登录界面</title>
    <!-- Bootstrap core CSS -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">

    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/examples/signin/signin.css" rel="stylesheet">

    <script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/assets/js/ie8-responsive-file-warning.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/assets/js/ie-emulation-modes-warning.js"></script>

    <script language="javascript" th:inline="javascript">
        function flushCode() {
            // 每次刷新的时候获取当前时间,防止浏览器缓存刷新失败
            var time = new Date();
            document.getElementById("scode").src="/StudentManage01/code?method=imageCode&time="+time;
        }
    </script>
    <style type="text/css">
        body{
            background-size:auto,auto;
            background-repeat: no-repeat;
        }
        .code-class{
            position: relative;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            padding: 10px;
            font-size: 16px;
            color: inherit;
            font: inherit;
            margin: 0;
            width: 180px;
            height: 44px;
            line-height: 1.42857143;
            color: #555;
            background-color: #fff;
            background-image: none;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
            -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
            transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
        }
        .identity{vertical-align: middle;height: 34px}
    </style>
</head>

<body>

<div class="container">

    <form class="form-signin" th:action="@{/student(method='Login')}" method="post">
        <h1>LOGIN</h1>
        <input type="text" id="inputEmail" name="userId" class="form-control" placeholder="账号" required autofocus>
        <br/>

        <input type="password" id="inputPassword" name="userPassword" class="form-control" placeholder="密码" required>

        <div >
            <input type="text" id="inputCode" name="code" class="code-class" placeholder="验证码" required>
            <img alt="验证码" id="scode" class="identity" onclick="flushCode()" th:src="@{/code(method='imageCode')}" >
        </div>
        <br/>

        <input class="btn btn-lg btn-primary btn-block" type="submit" value="登录"><br/>
    </form>

</div>

<script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>

登录页面使用了bootstrap,但是采用的是在线方式导入样式,所以需要联网才能显示效果。
可以看到页面有一个验证码的图片,这个验证码是通过后端进行绘制后返回给前端页面的。
访问的路径为:/StudentManage01/code?method=imageCode&time="+time;
在web.xml中有进行验证码路径的相关配置,发起的/code请求会交由CodeServlet进行处理。跟ProtalServlet一样,但是这里多了两个参数。我们先看下CodeServlet是怎么对验证码进行处理的。

CodeConstant

验证码图片长宽的参数定义。

public class CodeConstant {

    // 图片高度
    public static final int IMG_HEIGHT = 100;

    // 图片宽度
    public static final int IMG_WIDTH = 30;

    // 验证码长度
    public static final int CODE_LEN = 4;

}

CodeServlet

package com.lzk.servlet.model;

import com.lzk.constant.CodeConstant;
import com.lzk.servlet.base.ModelBaseServlet;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class CodeServlet extends ModelBaseServlet {

    public void imageCode(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 用于绘制图片,设置图片的长宽和图片类型(RGB)
        BufferedImage bi = new BufferedImage(CodeConstant.IMG_HEIGHT, CodeConstant.IMG_WIDTH, BufferedImage.TYPE_INT_RGB);
        // 获取绘图工具
        Graphics graphics = bi.getGraphics();
        graphics.setColor(new Color(100, 230, 200)); // 使用RGB设置背景颜色
        graphics.fillRect(0, 0, 100, 30); // 填充矩形区域

        // 验证码中所使用到的字符
        char[] codeChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456".toCharArray();
        String captcha = ""; // 存放生成的验证码
        Random random = new Random();
        for(int i = 0; i < CodeConstant.CODE_LEN; i++) { // 循环将每个验证码字符绘制到图片上
            int index = random.nextInt(codeChar.length);
            // 随机生成验证码颜色
            graphics.setColor(new Color(random.nextInt(150), random.nextInt(200), random.nextInt(255)));
            // 将一个字符绘制到图片上,并制定位置(设置x,y坐标)
            graphics.drawString(codeChar[index] + "", (i * 20) + 15, 20);
            captcha += codeChar[index];
        }
        // 将生成的验证码code放入sessoin中
        request.getSession().setAttribute("code", captcha);
        // 通过ImageIO将图片输出
        ImageIO.write(bi, "JPG", response.getOutputStream());
    }
}

这个类中对请求的处理跟ProtalServlet不一样,他有更具体的方法进行处理,而ProtalServlet是只针对Post请求和Get请求进行处理,而Post请求又调用Get请求的方法,因此ProtalServlet对请求只有一种应对方法,当然要想访问ProtalServlet也只能通过/进行。也就是一个请求路径对应一个Servlet,不管参数怎么变,对应的Servlet最多只能对不同请求进行两种不同的处理,一种为客户端发起Post请求时进行的处理,一种为Get。这种方式会非常繁琐,一是每个请求路径都要在web.xml进行配置,二是不好管理,例如对学生信息的增删改查,要写四个Servlet,而这四个Servlet关联性又很强。所以我们引入了ModelBaseServlet。

ModelBaseServlet

这个Servlet继承了ViewBaseServlet,所以也有模板渲染的功能并且通过暴力反射的方式去获取当前访问的方法名进行调用。所以当前端页面发起/StudentManage01/code?method=imageCode&time="+time;请求时,就会路径映射到codeServlet并且暴力反射调用CodeServlet中的imageCode。这种方式就可以实现针对CodeServlet中对验证码不同请求有多种不同的处理方式,只需要在里面写不同的方法即可。

package com.lzk.servlet.base;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class ModelBaseServlet extends ViewBaseServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //获取请求参数method的值
        String method = request.getParameter("method");
        //method参数的值就是要调用的方法的方法名,那就是已知方法名要去查找调用本对象的方法
        try {
            Method declaredMethod = this.getClass().getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);

            //暴力反射
            declaredMethod.setAccessible(true);
            //调用方法
            declaredMethod.invoke(this,request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

StudentServlet

现在是对学生信息数据方面的处理,通过该Servlet实现学生数据的增删改查。在这个Servlet中就可以看到引入的ModelBaseServlet的作用。里面可以实现四个方法,请求时只需要通过method参数指定请求的方法即可。
在登录页面点击登录按钮后会向@{/student(method='login')}发起请求,即调用login方法进行验证,成功则到list页面,失败则到·error页面。该servlet需渲染的页面后面都会提供。
Servlet在进行业务处理时会调用Service层,Servcie层调用Dao层。

package com.lzk.servlet.model;

import com.lzk.bean.PageInfo;
import com.lzk.bean.Student;
import com.lzk.service.StudentService;
import com.lzk.service.impl.StudentServiceImpl;
import com.lzk.servlet.base.ModelBaseServlet;
import org.apache.commons.beanutils.BeanUtils;

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

import java.util.*;
import java.util.List;

public class StudentServlet extends ModelBaseServlet {
    //创建Service对象
    private StudentService studentService = new StudentServiceImpl();

    //删除学生信息
    public void deleteStudent(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Integer id = Integer.valueOf(request.getParameter("id"));
        studentService.deleteStudentById(id);
    }

    //跳转到学生信息修改页面
    public void toStudentInfoPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取要修改的学生的id
        Integer id = Integer.valueOf(request.getParameter("id"));
        Long currentPage =  Long.valueOf(request.getParameter("currentPage"));

        Student student = new Student();
        Long pageSize = new PageInfo().getPageSize();
        //查询出当前学生的信息
        try {
            //查询指定学生信息
            if(!id.equals(-1)){
                student = studentService.findStudentById(id);
            }
            if(currentPage.equals(-1)){
                currentPage = studentService.getPageInfo(1L, pageSize).getTotalPage();
            }
            //将student存储到请求域中
            request.setAttribute("currentPage",currentPage);
            request.setAttribute("student", student);
            //跳转到修改页面
            processTemplate("student-update", request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //修改和增加学生信息
    public void updateOrAddStudent(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        Long currentPage = Long.valueOf(parameterMap.get("currentPage")[0]);
        Long pageSize = new PageInfo().getPageSize();
        if(currentPage==-1){
            currentPage = studentService.getPageInfo(1L, pageSize).getTotalPage()-1;
        }
        //将请求参数封装到Student对象
        Student student = new Student();
        try {
            BeanUtils.populate(student, parameterMap);
            System.out.println(student.toString());
            //调用业务层的方法执行修改
            if(student.getStudentId()!=null){
                studentService.updateStudent(student);
            }else{
                studentService.insertStudent(student);
            }
            request.setAttribute("currentPage",currentPage);
            processTemplate("list", request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //登录:查找登录用户是否存在
    public void login(HttpServletRequest request, HttpServletResponse response) throws Exception {
        long count = -1;
        try{
            //获取要登录的用户的id
            String id = String.valueOf(request.getParameter("userId"));
            //获取要登录的用户的密码
            String password = String.valueOf(request.getParameter("userPassword"));

            //调用业务层的方法查询用户是否存在
            count = studentService.findExistStudent(id, password);
            //验证码
            String code = (String) request.getSession().getAttribute("code");
            // 获取页面提交的验证码
            String inputCode = request.getParameter("code");
            //登录成功要同时满足用户存在且验证码正确
            boolean equals_code = code.toLowerCase().equals(inputCode.toLowerCase());
            if (count > 0 && equals_code) {
                //查询成功,解析Thymeleaf模板
                processTemplate("list", request, response);
            } else if(!equals_code){
                request.setAttribute("errorMsg", "验证码错误");
                processTemplate("error", request, response);
            } else {
                request.setAttribute("errorMsg", "用户不存在");
                processTemplate("error", request, response);
            }

        } catch (Exception e) {
            e.printStackTrace();
            //跳转到统一的异常提示页面
            request.setAttribute("errorMsg", e.getMessage());
            processTemplate("error", request, response);
        }

    }

    //获取分页学生列表数据
    public void getStudentList(HttpServletRequest request, HttpServletResponse response) throws Exception {

        Map<String, String[]> parameterMap = request.getParameterMap();

        //将请求参数封装到PageStudent对象
        PageInfo pageStudent = new PageInfo();

        //将请求域中的数据与每个pageStudent对应起来
        BeanUtils.populate(pageStudent, parameterMap);

        Long currentPage = pageStudent.getCurrentPage();
        Long pageSize = pageStudent.getPageSize();

        pageStudent = studentService.getPageInfo(currentPage, pageSize);
        //调用业务层的方法查询某一页的学生信息,所以currentPage需要前端处理好访问哪一页后传递过来
        List<Student> studentList = studentService.findStudentByPage(currentPage);
        //将pageStudent存储到请求域中
        request.setAttribute("pageInfo", pageStudent);
        //将某一页的学生信息存储到request一个名为list的对象中
        request.setAttribute("list", studentList);
        //跳转到展示页面
        processTemplate("student-table", request, response);

    }
}

StudentService

根据面向接口编程的原则,所以先实现这个接口。

面向接口的好处:当具体的业务逻辑要进行变更时,不需要改变Servlet层的代码,只需要重新写一个实现类去实现该接口,当然原先的接口也可以保存下来,只需要在导入实现类包的时候选择最新的那个。

package com.lzk.service;

import com.lzk.bean.PageInfo;
import com.lzk.bean.Student;

import java.sql.SQLException;
import java.util.List;

public interface StudentService {

    //查询某一页学生信息
    List<Student> findStudentByPage(long pagenumber) throws Exception;

    //删除学生信息
    public void deleteStudentById(Integer id) throws Exception;

    //添加学生信息
    public void insertStudent(Student student) throws Exception;

    //查询指定学生信息
    public Student findStudentById(Integer id) throws Exception ;

    //修改学生信息
    public void updateStudent(Student student) throws Exception;

    //查询学生是否存在
    public long findExistStudent(String id,String name) throws Exception;

    //查询学生总数
    public long findAllStudentCount() throws Exception;

    //返回学生的分页导航数据
    PageInfo getPageInfo(Long currentPage, Long pageSize) throws Exception;

}

StudentServiceImpl

package com.lzk.service.impl;


import com.lzk.bean.PageInfo;
import com.lzk.bean.Student;
import com.lzk.dao.StudentDao;
import com.lzk.dao.impl.StudentDaoImpl;
import com.lzk.service.StudentService;

import java.sql.SQLException;
import java.util.List;

public class StudentServiceImpl implements StudentService {
    //创建Dao对象
    private StudentDao studentDao = new StudentDaoImpl();

    //查询某一页学生信息
    @Override
    public List<Student> findStudentByPage(long currentpage) throws Exception {
        return studentDao.findStudentByPage(currentpage);
    }

    //删除学生信息
    @Override
    public void deleteStudentById(Integer id) throws Exception{
        studentDao.deleteStudentById(id);
    }
    //添加学生信息
    @Override
    public void insertStudent(Student student) throws Exception {
        studentDao.insertStudent(student);
    }
    //查询指定学生信息
    @Override
    public Student findStudentById(Integer id) throws Exception {
        return studentDao.findStudentById(id);
    }
    //修改学生信息
    @Override
    public void updateStudent(Student student) throws Exception {
        studentDao.updateStudent(student);
    }
    //查询学生是否存在
    public long findExistStudent(String id,String password) throws Exception{
        return studentDao.findExistStudent(id, password);
    }
    //查询学生总数
    public long findAllStudentCount() throws Exception{
        return studentDao.findAllStudnetCount();
    }

    @Override
    public PageInfo getPageInfo(Long currentPage,Long pageSize) throws SQLException {
        long totalCount = studentDao.findAllStudnetCount();
        long totalPage = totalCount % pageSize == 0 ? totalCount/pageSize : totalCount/pageSize + 1;
        Long nextPage = null;
        Long previousPage = null;
        if(currentPage < totalPage-1){
            nextPage = currentPage + 1;
        }
        if(currentPage != 0){
            previousPage = currentPage - 1;
        }
        PageInfo pageInfo = new PageInfo(currentPage,pageSize,totalCount,totalPage,previousPage,nextPage);
        return pageInfo;
    }
}

StudentDao

Service需要调用Dao层

为什么要分为三层,而不让StudentService直接处理完呢?
其实每一层都有对应的功能,servlet负责请求的处理,service负责具体的业务逻辑处理,dao层负责对数据库数据的处理。分为三层可以解耦合,让结构更为清晰。

package com.lzk.dao;

import com.lzk.bean.PageInfo;
import com.lzk.bean.Student;

import java.sql.SQLException;
import java.util.List;

public interface StudentDao {
    //查询所有学生信息
    List<Student> findAll() throws SQLException;

    //查询某一页学生信息
    List<Student> findStudentByPage(long pagenumber) throws SQLException;

    //删除学生信息
    void deleteStudentById(Integer id) throws SQLException;

    //添加学生信息
    void insertStudent(Student student) throws SQLException;

    //查询指定学生信息
    Student findStudentById(Integer id) throws SQLException;

    //修改学生信息
    void updateStudent(Student student) throws SQLException;

    //根据学号,姓名查询学生是否存在,k
    long findExistStudent(String id,String password) throws SQLException;

    //查询数据总数
    long findAllStudnetCount() throws SQLException;


}

list页面

list页面只展示导航条部分数据,学生数据是通过页面加载时发起th:onload="|getStudentListByPage(${currentPage == null ? 0 : currentPage})|"请求去获取的。这个方法在后面的student.js里。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>展示学生列表信息</title>

    <!-- Bootstrap core CSS -->
    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/dist/css/bootstrap.min.css" rel="stylesheet">

    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet">

    <link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.25/examples/dashboard/dashboard.css" rel="stylesheet">

    <script src="js/jquery-1.8.3.js"></script>
    <script src="js/student.js"></script>
</head>
<body th:onload="|getStudentListByPage(${currentPage == null ? 0 : currentPage})|">
    <div>
        <nav class="navbar navbar-inverse navbar-fixed-top">
            <div class="container-fluid">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#">学生信息管理系统</a>
                </div>

            </div>
        </nav>

        <div class="row">
            <div class="col-sm-3 col-md-2 sidebar">
                <ul class="nav nav-sidebar">
                    <li><a th:onclick="getStudentListByPage(0)" style="cursor: pointer">分页学生信息</a></li>
                    <li><a th:onclick="toStudentInfoPage(-1,-1)" style="cursor: pointer">添加学生信息</a></li>
                </ul>
            </div>

            <div id="content"></div>
        </div>
    </div>
</body>
</html>

student.js

第一次发起的请求为:student?method=getStudentList&currentPage=0,这个请求还是通过web.xml中配置的StudentServlet处理,处理逻辑看上面的StudentServlet中的getStudentList方法。其中的PageInfo包装了分页信息。

//异步加载学生信息列表
function getStudentListByPage(currentPage) {
    $.ajax({
        url: 'student?method=getStudentList&currentPage='+currentPage,
        type: 'GET',
        success: function(response) {
            $("#content").empty();
            $("#content").html(response)
        }
    });
}
//删除学生信息
function deleteStudentById(studentId,currentPage) {
    $.ajax({
        url: 'student?method=deleteStudent&id=' + studentId,
        type: 'GET',
        success: function () {
            getStudentListByPage(currentPage);
        }
    });
}

function showAppointPage() {
    var current = document.getElementById("appointPage").value;
    getStudentListByPage(current-1);
}

function toStudentInfoPage(studentId,currentPage) {
    $.ajax({
        url: 'student',
        type: 'GET',
        data: { 'method': 'toStudentInfoPage', 'id': studentId, 'currentPage': currentPage},
        success: function(response) {
            $("#content").empty();
            $("#content").html(response)
        }
    });
}

function updateOrAddStudent() {
    // 获取表单数据
    var formData = new FormData(document.getElementById('myForm'));
    $.ajax({
        url: 'student',
        type: 'post',
        data: formData,
        contentType: false
    });

}

function checkPage() {
    var appointPage = parseInt($("#appointPage").val());
    var totalPage = parseInt($("#totalPage").text());

    if (appointPage < 0 ) {
        $("#appointPage").val("1");
    }else if(appointPage > totalPage){
        $("#appointPage").val("1");
    }
}

student-table.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
</head>
<body>

<div class="col-sm-8 col-sm-offset-3 col-md-10 col-md-offset-2 main" >

    <h1 class="sub-header">List Student</h1>

    <div class="table-responsive" >
        <table class="table table-striped" th:unless="${#lists.isEmpty(list)}" border="1" cellspacing="0" width="800">
            <thead>
            <tr>
                <th style="text-align:center">学生的编号</th>
                <th style="text-align:center">学生的姓名</th>
                <th style="text-align:center">学生的班级</th>
                <th>删除信息</th>
                <th>修改信息</th>
            </tr>
            </thead>
            <!--   如果没有学生信息,则显示没有学生数据,请添加学生  -->
            <tbody th:if="${#lists.isEmpty(list)}">
            <tr>
                <td th:colspan="5">没有学生数据,请添加学生</td>
            </tr>
            </tbody>
            <!--  如果有学生信息,则遍历展示学生信息   -->
            <tbody th:unless="${#lists.isEmpty(list)}">
            <!--  使用th:each遍历域对象里面的集合    -->
            <tr  th:each="student : ${list}">
                <td th:text="${student.studentId}" align="center">学生的编号</td>
                <td th:text="${student.studentName}" align="center">学生的姓名</td>
                <td th:text="${student.studentClass}" align="center">学生的班级</td>
                <td><a th:onclick="|deleteStudentById(${student.studentId},${pageInfo.currentPage})|" style="cursor: pointer">删除信息</a></td>
                <td><a th:onclick="|toStudentInfoPage(${student.studentId},${pageInfo.currentPage})|" style="cursor: pointer">修改</a></td>
            </tr>
            </tbody>
            <!--   页面导航的超链接    -->
            <tr th:unless="${#lists.isEmpty(list)}">
                <td  colspan="5" align="center"><span id="totalPage" th:text="${pageInfo.totalPage}">共多少页</span>页  第<span th:text="${pageInfo.currentPage}+1">第几页</span></td>
            </tr >
            <tr th:unless="${#lists.isEmpty(list)}">

                <td colspan="5" align="center" >

                    <input type="button" value="跳转"  onclick="showAppointPage()" />
                    <input style="width:70px;" id="appointPage"  th:value="${pageInfo.currentPage+1}" onkeyup="checkPage()" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    <input type="button" value="首页"  onclick="getStudentListByPage(0)" />
                    <input th:if="${pageInfo.previousPage != null}" type="button" value="上一页"  th:onclick="|getStudentListByPage(${pageInfo.previousPage})|" />
                    <input th:if="${pageInfo.nextPage != null}" type="button" value="下一页"  th:onclick="|getStudentListByPage(${pageInfo.nextPage})|" />
                    <input type="button" value="尾页"  th:onclick="|getStudentListByPage(${pageInfo.totalPage-1})|" />
                    <br/>
                </td>
            </tr>
        </table>
    </div>
</div>

</body>
</html>

error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>错误页面</title>

    <script language="javascript" th:inline="javascript">
        //返回登录页面
        function backLogin() {
            window.location.href = "portalServlet";
        }
    </script>

    <style type="text/css">
        .back-button{
            width: 65px;
            color: #fff;
            background-color: #337ab7;
            border-color: #2e6da4;
            -ms-touch-action: manipulation;
            border: 1px solid transparent;
            padding: 6px 12px;
            font-size: 14px;
            line-height: 1.42857143;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div align="center">
        <img src="image/pange.gif" >
        <h1 th:text="${errorMsg}">显示一个动态的错误信息</h1>
        <input class="back-button" type="submit"  onclick="backLogin()" value="返回"><br/>
    </div>

</body>
</html>

student-insertion.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>学生信息添加页面</title>
    <base th:href="@{/}"/>
    <script type="text/javascript" src="js/jquery-1.8.3.js"></script>
    <link href="/bootstrap-3.4.1-dist/css/bootstrap.css" rel="stylesheet">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        function check() //onsubmit:return true:表单正常提交,return false表单终止
        {
            var sno=$("#stu_name").val();
            var sname=$("#stu_class").val();
            if(!(sno.length>1&&sno.length<10)){
                alert("填写姓名信息有误!");
                return false;
            }
            if(!(sname.length>2&&sname.length<10)){
                alert("班级信息有误!")
                return false;
            }
            return true;
        }
    </script>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-12 ">
            <form th:action="@{/student(method='insertStudent')}" method="post" class="form-horizontal" onsubmit="return check()">
                <!-- 表单区域-->
                <fieldset>
                    <!--表单主题-->
                    <legend>填写新增学生信息</legend>
                    <!-- 每一个form-group都可以自定义布局-->
                    <tr ><a th:href="@{/student(method='LoginSuccess')}">返回</a></tr>
                    <div class="form-group">
                        <!-- label表示文字提示标签,可以通过表单的组建的id提示-->

                        <label class="col-md-2 control-label" for="stu_name">学生姓名</label>
                        <div class="col-md-4">
                            <input class="form-control" input type="text" id="stu_name" name="studentName"/>
                        </div>
                    </div>

                    <div class="form-group">
                        <!-- label表示文字提示标签,可以通过表单的组建的id提示-->
                        <label class="col-md-2 control-label" for="stu_class">学生班级</label>
                        <div class="col-md-4">
                            <input class="form-control" type="text" id="stu_class" name="studentClass"/>
                        </div>
                    </div>

                    <div class="form-group">
                        <div class="col-md-6 col-md-offset-3">
                            <input class="btn btn-primary" type="submit" value="添加"/>
                            <input class="btn btn-warning" type="reset" value="重置"/>
                        </div>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>
</div>
</body>
</html>

student-update.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
<div>
    <div style="width: 75%;padding-left: 25%;padding-top: 2%">
        <!-- 表单区域-->
        <form id="myForm">
        <fieldset>
            <legend th:if="${student.studentId != null}">修改学生信息</legend>
            <legend th:if="${student.studentId == null}">添加学生信息</legend>
            <input type="hidden" name="method" value="updateOrAddStudent">
            <input type="hidden" name="currentPage" th:value="${currentPage == null ? -1 : currentPage}" placeholder="Appoint Page">
            <div class="form-group row"  th:if="${student.studentId != null}" >
                <label class="col-md-2 control-label" for="stu_id">学生学号</label>
                <div class="col-md-4">
                    <input class="form-control" readonly="readonly" type="text" id="stu_id" th:value="${student.studentId}" name="studentId" />
                </div>
            </div>
            <div class="form-group row">
                <label class="col-md-2 control-label" for="stu_name">学生姓名</label>
                <div class="col-md-4">
                    <input th:if="${student.studentId != null}" class="form-control" type="text" id="stu_name" th:value="${student.studentName}" name="studentName"/>
                    <input th:if="${student.studentId == null}" class="form-control" type="text" id="stu_name" th:value="${student.studentName}" name="studentName"/>
                </div>
            </div>

            <div class="form-group row">
                <label class="col-md-2 control-label" for="stu_class">学生班级</label>
                <div class="col-md-4">
                    <input th:if="${student.studentId != null}" class="form-control" type="text" id="stu_class" th:value="${student.studentClass}" name="studentClass"/>
                    <input th:if="${student.studentId == null}" class="form-control" type="text" id="stu_class" th:value="${student.studentClass}" name="studentClass"/>
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-6 col-md-offset-3">
                    <input th:if="${student.studentId != null}"class="btn btn-primary" type="submit" value="修改" onclick="updateOrAddStudent()"/>
                    <input th:if="${student.studentId == null}" class="btn btn-primary" type="submit" value="添加" onclick="updateOrAddStudent(-1)"/>
                    <input class="btn btn-warning" type="reset" value="重置"/>
                </div>
            </div>
        </fieldset>
        </form>
    </div>
</div>

</body>
</html>
  • 17
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
该学生成绩信息管理系统涉及到学生、教师、系统管理员、班级、学生成绩、课程。设置一个系统管理员对系统进行管理。所有用户需输入账号、密码登录进入系统;管理员进入系统后可对学生、老师、班级、课程进行增删改查操作;学生进入系统,查看成绩、查看和修改自己的信息;老师进入系统后,对自己这门课程的学生设置课程成绩、查看和修改自己的信息,查看学生的信息和成绩、以及统计分析学生的成绩; 管理员为班级设置年级,为年级设置课程,为班级的每门课程设置老师,为学生设置班级。一个年级有多门课程(语文、数学、外语等等),班级的每门课程只能有一名老师,一个老师可以有多门课程;老师选择自己这门课程为该课程的学生登记成绩。老师可以查看其他老师的信息(可以当成是老师的通讯录),查看本课程学生的信息和成绩;学生可以查看班级其他同学的信息(可以看成是班级的同学录)。 考试分为两种,一种是年级统考,一种是平时考试。年级统考需要管理员事先添加一次年级统考,考试成绩出来后,老师进入系统选择该次考试为学生登记成绩。平时考试则是班级平时的考试,老师添加考试信息,登记成绩。成绩统计分析则是针对年级统考进行分析,主要涉及各学科分数名次,总分名次。 技术实现 系统环境:Windows开发工具:IDEAJava版本:JDK 1.8服务器:Tomcat 1.8数据库:MySQL 5.X系统采用技术:Servlet+Jsp+Jdbc+H-ui+EasyUI+jQuery+Html+Css+Ajax 系统功能系统主要分为三种用户角色,分别是管理员、老师以及学生,其具体功能如下: - 管理员   学生信息管理、教师信息管理、年级信息管理、班级信息管理、课程信息管理、考试信息管理,系统参数设置 - 老师   教学管理、教师个人信息维护、教师通讯录管理 - 学生考试成绩查询、学生通讯录、学生个人信息维护 运行截图 登录界面: 管理员界面: 考试列表:  成绩统计: 学生信息管理: 教师信息管理: 年级、班级信息管理:  系统设置: 教师界面:  成绩登记:  教师通讯录: 个人信息:  学生界面: 学生成绩查询: 班级通讯录: 学生个人信息:              
JavaWeb“系统管理”项目资源概览 一、内容概览 这个JavaWeb“系统管理”项目资源包,是专为对JavaWeb开发有兴趣的学习者设计的。它包含了从基础到高级的完整知识体系,以及实际项目操作的全部流程。具体内容包括: 项目背景与目标:详细介绍了“系统管理”项目的起源、目的和核心功能。 技术栈概览:涵盖了Spring、SpringMVC、MyBatis等主流JavaWeb框架的使用,以及MySQL数据库的管理。 项目模块解析:按照实际项目结构,分模块介绍了后台管理、用户权限管理、数据报表生成等功能的具体实现。 代码与实现细节:提供了完整的项目源代码,并针对关键部分进行了详细的注释和解析。 文档与笔记:整理了开发过程中的关键决策、技术难题以及学习心得,有助于深入理解项目背后的思考过程。 二、适用人群 这个项目资源包适用于即将毕业或已经毕业,希望通过实际项目经验增强自己JavaWeb开发能力的同学。无论你是初学者还是有一定经验的开发者,都可以从中获得宝贵的实践经验和技能提升。 三、使用建议 理论与实践相结合:在学习过程中,不仅要关注代码实现,更要理解背后的设计思想和原理。 模块化学习:建议按照项目模块进行学习,从基础到高级,逐步深入。 持续实践与反思:通过实JavaWeb“系统管理”项目资源概览 一、内容概览 这个JavaWeb“系统管理”项目资源包,是专为对JavaWeb开发有兴趣的学习者设计的。它包含了从基础到高级的完整知识体系,以及实际项目操作的全部流程。具体内容包括: 项目背景与目标:详细介绍了“系统管理”项目的起源、目的和核心功能。 技术栈概览:涵盖了Spring、SpringMVC、MyBatis等主流JavaWeb框架的使用,以及MySQL数据库的管理。 项目模块解析:按照实际项目结构,分模块介绍了后台管理、用户权限管理、数据报表生成等功能的具体实现。 代码与实现细节:提供了完整的项目源代码,并针对关键部分进行了详细的注释和解析。 文档与笔记:整理了开发过程中的关键决策、技术难题以及学习心得,有助于深入理解项目背后的思考过程。 二、适用人群 这个项目资源包适用于即将毕业或已经毕业,希望通过实际项目经验增强自己JavaWeb开发能力的同学。无论你是初学者还是有一定经验的开发者,都可以从中获得宝贵的实践经验和技能提升。 三、使用建议 理论与实践相结合:在学习过程中,不仅要关注代码实现,更要理解背后的设计思想和原理。 模块化学习:建议按照项目模块进行学习,从基础到高级,逐步深入。 持续实践与反思:通过实JavaWeb“系统管理”项目资源概览 一、内容概览 这个JavaWeb“系统管理”项目资源包,是专为对JavaWeb开发有兴趣的学习者设计的。它包含了从基础到高级的完整知识体系,以及实际项目操作的全部流程。具体内容包括: 项目背景与目标:详细介绍了“系统管理”项目的起源、目的和核心功能。 技术栈概览:涵盖了Spring、SpringMVC、MyBatis等主流JavaWeb框架的使用,以及MySQL数据库的管理。 项目模块解析:按照实际项目结构,分模块介绍了后台管理、用户权限管理、数据报表生成等功能的具体实现。 代码与实现细节:提供了完整的项目源代码,并针对关键部分进行了详细的注释和解析。 文档与笔记:整理了开发过程中的关键决策、技术难题以及学习心得,有助于深入理解项目背后的思考过程。 二、适用人群 这个项目资源包适用于即将毕业或已经毕业,希望通过实际项目经验增强自己JavaWeb开发能力的同学。无论你是初学者还是有一定经验的开发者,都可以从中获得宝贵的实践经验和技能提升。 三、使用建议 理论与实践相结合:在学习过程中,不仅要关注代码实现,更要理解背后的设计思想和原理。 模块化学习:建议按照项目模块进行学习,从基础到高级,逐步深入。 持续实践与反思:通过实际操作项目,不断反思和总结,形成自己的技术见解和经验。 参与社区讨论:与同行交流心得,共同成长,拓宽视野。际操作项目,不断反思和总结,形成自己的技术见解和经验。 参与社区讨论:与同行交流心得,共同成长,拓宽视野。际操作项目,不断反思和总结,形成自己的技术见解和经验。 参与社区讨论:与同行交流心得,共同成长,拓宽视野。
一、项目简介本课程演示的是一套基于SSM实现的在线音乐网站,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。课程包含:1. 项目源码、项目文档、数据库脚本、软件工具等所有资料2. 带你从零开始部署运行本套系统3. 该项目附带的源码资料可作为毕设使用4. 提供技术答疑二、技术实现后台框架:Spring、SpringMVC、MyBatisUI界面:JSP、jQuery 、H-ui数据库:MySQL 三、系统功能本在线音乐网站采用JSP动态网页开发技术,JAVA编程语言,基于B/S架构,使用SSM框架技术,使用MySQL数据库,充分保证了系统的稳定性和安全性。该系统主要分为前台和后台两大功能模块,共包含两个角色:用户、管理员。具体的系统功能如下:1.前台功能 前台首页、音乐浏览、音乐搜索、音乐分类查找、音乐详情、音乐播放、音乐下载、添加收藏、新闻公告、留言交流、用户注册、用户登陆、个人中心、用户信息修改、我的收藏、意见反馈、修改密码等功能。2.后台功能 后台系统登陆、管理员管理、用户信息管理、音乐管理、音乐类型管理、新闻公告管理、用户评价管理、意见反馈管理、留言交流管理、消息回复管理等功能。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 四、项目截图1)前台首页2)音乐详情播放3)我的收藏4)音乐信息管理5)新增音乐  更多Java毕设项目请关注【毕设系列课程】https://edu.csdn.net/lecturer/2104   
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于Servlet+JSP+JavaBean的新生管理系统源码+数据库+部署说明(javaweb高分课设).zip # JavaWeb项目之新生管理系统(Servlet+JSP+JavaBean) ## 项目介绍 ### 功能介绍 -登录,登出和登录验证 -新生报到:     新生录取信息管理:条件搜索新生,搜索结果以列表的形式给出,可以对列表中的客户信息进行编辑和删除,导入新生信息     班级分配:修改新生班级     专业调整:修改新生系别和专业     财务缴费:条件搜索新生缴费情况,搜过结果以列表的形式给出 -宿舍管理:条件搜索宿舍,搜索结果以列表的形式给出,管理宿舍人员(查看人员,增加人员,删除人员) -班级管理:条件搜索班级,搜索结果以列表的形式给出,管理班级人员(查看人员,增加人员,删除人员) -成绩管理:条件搜索成绩,搜索结果以列表的形式给出 -用户管理:管理员修改密码 ### 运用知识 -数据库基本查询 -数据库连接池c3p0 -运用dbutil.jar包一键封装表单数据到bean对象中,简化对数据库增、删、改、查的代码 -运用fileupload.jar包上传文件 -运用poi.jar包解析EXCEL文件 -AJAX异步更新 -运用json-lib.jar包将数据转化为JSON格式 -标签库JSTL -JavaWeb三层框架的分离 ## 准备 1.导入第三方包,c3p0配置文件和db.proerties数据库配置文件 2、建包 -dao,dao.impl -service,service.impl -servlet.controller,servle.filter,servle.UI -domain ## 搭建环境 IntelliJ IDEA +MySQL
学生宿舍管理系统是一种基于Java Web的应用程序,旨在帮助学校管理学生宿舍的入住、退宿、维修等事务。源码包含了系统的前端设计和后端逻辑。 前端设计方面,源码使用了HTML、CSS和JavaScript来构建用户界面。通过布局合理的网页,学生和管理员可以方便地进行系统操作,如登录、预定宿舍、查询宿舍信息等。前端还利用JavaScript实现了一些交互功能,如表单验证、模态框等,提升了用户体验。 后端逻辑方面,源码使用了Java语言编写。通过Spring MVC框架,实现了各层之间的解耦和业务逻辑的处理。系统的核心功能包括学籍管理、宿舍管理和维修管理。学生和管理员可以通过不同的权限进行相关操作,如学生可以进行宿舍预定和查询,管理员可以进行宿舍入住的审核和学生宿舍调整等。 源码中还包含数据库的设计和操作。通过使用MySQL数据库,系统可以存储和检索各种相关数据,如学生信息、宿舍信息、维修记录等。通过Hibernate框架,实现了ORM映射和数据库操作的简化,提高了开发效率。 除此之外,源码还涵盖了一些其他功能,如宿舍楼层、宿舍床位的统计和显示,维修记录的查询和报修处理等。通过源码的学习和使用,可以帮助开发者更好地理解和掌握Java Web开发的技术和方法,从而为其他类似项目的开发提供参考和指导。 总之,javaweb学生宿舍管理系统的源码是一个完整的系统实现,通过前端设计和后端逻辑的结合,实现了学生宿舍管理的各项功能。通过源码的学习和应用,可以提升开发者的Java Web开发能力,并为学生宿舍管理等项目的开发提供参考和帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值