实验11-12 基于SpringMVC+Hibernate框架的学生选课分页显示页面的设计

实验11-12 基于SpringMVC+Hibernate框架的学生选课分页显示页面的设计

实验目的

熟练掌握数据库分页技术在 JSP 页面中的实际开发,学会使用 SpringMVC+Hibernate 分层架构完成分页查询,理解物理分页实现思路,掌握通用分页工具类封装、ORM 持久层查询、前端分页交互整套流程。

实验需求与设计思路

功能需求

  • 创建 MySQL 学生选课表
    字段包含:学号、课程号、课程名、学时数、任课教师、授课地点、学年、学期,插入至少 30 条测试数据

  • 采用 SpringMVC+Hibernate 三层架构开发选课查询页面

  • 分页规则
    每页固定展示 6 条选课数据

  • 前端 JSP 页面展示表格
    提供分页跳转按钮,UI 简洁美观

  • 实现数据库物理分页,减少内存加载压力

整体分层设计

  • Model 层
    StudentCourse实体类、通用分页工具PageBean

  • Dao 持久层
    BaseDao基础父类、StudentCourseDao实现分页查询

  • Service 业务层
    封装分页业务逻辑,添加事务控制

  • Controller 控制层
    接收前端页码参数,传递分页数据到视图

  • View 视图层
    JSP 页面循环渲染选课列表、分页按钮

实验成果

代码分析

PageBean.java(util 包)

点击查看代码
package util;

import java.util.List;

public class PageBean<T> {
    private Integer currentPage;
    private final Integer pageSize = 6;
    private Integer totalCount;
    private List<T> list;

    // 自动计算总页数
    public Integer getTotalPage() {
        if(totalCount == null || totalCount <=0) return 0;
        return totalCount % pageSize == 0 ? totalCount/pageSize : totalCount/pageSize +1;
    }

    // getter setter
    public Integer getCurrentPage() {return currentPage;}
    public void setCurrentPage(Integer currentPage) {this.currentPage = currentPage;}
    public Integer getPageSize() {return pageSize;}
    public Integer getTotalCount() {return totalCount;}
    public void setTotalCount(Integer totalCount) {this.totalCount = totalCount;}
    public List<T> getList() {return list;}
    public void setList(List<T> list) {this.list = list;}
}

StudentCourse.java(entity 包)

点击查看代码
package entity;

public class StudentCourse {
    private Integer id;
    private String stuNo;        //学号
    private String courseNo;    //课程号
    private String courseName;  //课程名
    private Integer classHour;  //学时
    private String teacherName; //教师
    private String classRoom;   //教室
    private String schoolYear;  //学年
    private Integer term;       //学期

    public StudentCourse(){}

    // getter setter
    public Integer getId() {return id;}
    public void setId(Integer id) {this.id = id;}
    public String getStuNo() {return stuNo;}
    public void setStuNo(String stuNo) {this.stuNo = stuNo;}
    public String getCourseNo() {return courseNo;}
    public void setCourseNo(String courseNo) {this.courseNo = courseNo;}
    public String getCourseName() {return courseName;}
    public void setCourseName(String courseName) {this.courseName = courseName;}
    public Integer getClassHour() {return classHour;}
    public void setClassHour(Integer classHour) {this.classHour = classHour;}
    public String getTeacherName() {return teacherName;}
    public void setTeacherName(String teacherName) {this.teacherName = teacherName;}
    public String getClassRoom() {return classRoom;}
    public void setClassRoom(String classRoom) {this.classRoom = classRoom;}
    public String getSchoolYear() {return schoolYear;}
    public void setSchoolYear(String schoolYear) {this.schoolYear = schoolYear;}
    public Integer getTerm() {return term;}
    public void setTerm(Integer term) {this.term = term;}
}

BaseDao.java(dao 包)

点击查看代码
package dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class BaseDao {
    @Autowired
    private SessionFactory sessionFactory;
    public Session getSession(){
        return sessionFactory.getCurrentSession();
    }
}

StudentCourseDao.java

点击查看代码
package dao;

import entity.StudentCourse;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;
import util.PageBean;

import java.util.List;

@Repository
public class StudentCourseDao extends BaseDao {
    public PageBean<StudentCourse> pageQuery(Integer currentPage){
        PageBean<StudentCourse> page = new PageBean<>();
        page.setCurrentPage(currentPage);
        int size = page.getPageSize();

        org.hibernate.Session session = getSession();
        Transaction tx = session.beginTransaction();

        // 查询总记录数
        Query countQ = session.createQuery("select count(*) from StudentCourse");
        Long total = (Long) countQ.uniqueResult();
        page.setTotalCount(total.intValue());

        // 分页截取数据
        Query dataQ = session.createQuery("from StudentCourse");
        dataQ.setFirstResult((currentPage-1)*size);
        dataQ.setMaxResults(size);
        List<StudentCourse> list = dataQ.list();
        page.setList(list);

        tx.commit();
        return page;
    }
}

StudentCourseService.java

点击查看代码
package service;

import dao.StudentCourseDao;
import entity.StudentCourse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import util.PageBean;

@Service
public class StudentCourseService {
    @Autowired
    private StudentCourseDao dao;

    @Transactional(readOnly = true)
    public PageBean<StudentCourse> getPage(Integer pageNum){
        // 页码为空或小于1,默认第一页
        if(pageNum == null || pageNum <1) pageNum = 1;
        return dao.pageQuery(pageNum);
    }
}

CourseController.java

点击查看代码
package controller;

import entity.StudentCourse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import service.StudentCourseService;
import util.PageBean;

@Controller
@RequestMapping("/course")
public class CourseController {
    @Autowired
    private StudentCourseService service;

    @RequestMapping("/list")
    public String list(@RequestParam(value="page",required = false) Integer page, Model model){
        PageBean<StudentCourse> pageData = service.getPage(page);
        model.addAttribute("pageData",pageData);
        return "courseList";
    }
}

courseList.jsp 前端分页页面

点击查看代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>学生选课分页查询系统</title>
    <style>
        table{width:90%;margin:20px auto;border-collapse: collapse;}
        th,td{border:1px solid #999;padding:8px;text-align:center}
        th{background:#007bff;color:white}
        .page-box{text-align:center;margin:20px}
        a{margin:0 5px;text-decoration:none}
    </style>
</head>
<body>
    <h2 style="text-align:center">学生选课信息分页展示</h2>
    <table>
        <tr>
            <th>学号</th>
            <th>课程号</th>
            <th>课程名称</th>
            <th>学时</th>
            <th>授课教师</th>
            <th>上课地点</th>
            <th>学年</th>
            <th>学期</th>
        </tr>
        <!-- 遍历分页数据 -->
        <c:forEach items="${pageData.list}" var="sc">
            <tr>
                <td>${sc.stuNo}</td>
                <td>${sc.courseNo}</td>
                <td>${sc.courseName}</td>
                <td>${sc.classHour}</td>
                <td>${sc.teacherName}</td>
                <td>${sc.classRoom}</td>
                <td>${sc.schoolYear}</td>
                <td>${sc.term==1?'第一学期':'第二学期'}</td>
            </tr>
        </c:forEach>
    </table>

    <div class="page-box">
        总记录:${pageData.totalCount}条,共${pageData.totalPage}页
        <br>
        <!-- 上一页 -->
        <c:if test="${pageData.currentPage > 1}">
            <a href="/course/list?page=${pageData.currentPage-1}">上一页</a>
        </c:if>
        当前第${pageData.currentPage}页
        <!-- 下一页 -->
        <c:if test="${pageData.currentPage < pageData.totalPage}">
            <a href="/course/list?page=${pageData.currentPage+1}">下一页</a>
        </c:if>
    </div>
</body>
</html>

结果介绍

image

image

网站访问链接:http://47.111.183.105:8080/CourseSelect/index.jsp

问题解决

问题一:首次访问无 page 参数,页码为 0 分页错乱

解决:Service 层增加判断,page 为空或小于 1 强制赋值为 1,保证分页偏移量计算正确。

问题二:总页数计算出现余数丢失

解决:修改 PageBean 的getTotalPage(),使用三元运算符判断取模结果,有余数则页数 + 1。

问题三:页面布局简陋,UI 不美观

解决:添加 CSS 样式美化表格、分页区域,调整文字居中、配色,提升页面观感。

实验总结

这次实验完整做完了 MVC 分层搭配 Hibernate 的选课分页功能,从头到尾完整走了一遍开发流程:从建数据库表、写分层后端代码、封装分页计算工具,再到 JSP 页面渲染展示全部实操完成。
通过动手敲代码,我们真正分清了三层架构每一层的职责,也体会到 Hibernate 这种 ORM 框架不用手写大量 SQL,大大简化数据库操作,彻底吃透分页功能底层实现原理。
写代码过程中踩了不少分页边界、事务、参数接收的坑,一步步排查修复,也锻炼了自己调试代码、定位 bug 的能力,同时意识到分层封装、页码边界判断、数据库事务管理在 Web 项目里缺一不可。

posted @ 2026-06-19 11:52  呼儿嘿哟。  阅读(4)  评论(0)    收藏  举报