计算机学院管理系统(2)
1. 学生信息管理页面(数据库)
1.1 数据库设计
字段名 | 数据类型 | 属性 | 备注 |
---|---|---|---|
id | int | not null(非空) 主键 自增长 | ID字段 |
StudentNum | varchar | not null 唯一键 | 学号 |
StuClass | varchar | 班级 | |
StudentName | varchar | 学生姓名 | |
sex | char | 性别 | |
PhoneNum | varchar | 联系方式 | |
Address | varchar | 家庭地址 | |
SchoolAddress | varchar | 住宿信息 | |
Rid | int | 档案ID |
1.2 数据库脚本
-- 创库
drop database if exists codb; #检测如果存在codb表就删除
create database codb character set utf8; #新建codb表 设置UTF-8
use codb; #使用codb表
#学生信息表 Student
drop table if exists Student;
create table Student(
id int(11) not null primary key auto_increment comment '主键',
StudentNum varchar(60) not null unique comment '学号',
StuClass varchar(60) comment '班级',
StudentName varchar(60) comment '学生姓名',
sex char(2) comment '性别',
PhoneNum varchar(20) comment '联系方式',
Address varchar(100) comment '家庭地址',
SchoolAddress varchar(100) comment '住宿信息',
Rid int(11) comment '档案ID'
);
insert into Student values(null,180403190,'18级计科5班','张三','男','13435022217','武汉市武昌区水果湖街道','1区2号楼304寝',1);
insert into Student values(null,180403191,'18级计科6班','李四','女','13435024237','武汉市武昌区水果湖街道','2区2号楼103寝',2);
insert into Student values(null,180403192,'18级大数据2班','王五','男','13435022219','武汉市武昌区水果湖街道','3区1号楼614寝',3);
insert into Student values(null,180403193,'18级大数据3班','赵六','女','13435022216','武汉市武昌区水果湖街道','1区2号楼304寝',4);
insert into Student values(null,180403194,'18级计科5班','丁七','男','13435022245','武汉市武昌区水果湖街道','1区2号楼404寝',5);
insert into Student values(null,180403195,'18级计科5班','刘八','女','13435022256','武汉市武昌区水果湖街道','3区1号楼205寝',6);
insert into Student values(null,180403196,'18级计科5班','袁九','男','13435022457','武汉市武昌区水果湖街道','1区2号楼322寝',7);
insert into Student values(null,180403197,'18级大数据3班','小莉','女','13435045417','武汉市武昌区水果湖街道','2区2号楼317寝',8);
insert into Student values(null,180403198,'18级大数据3班','小刚','男','13435022217','武汉市武昌区水果湖街道','2区2号楼524寝',9);
insert into Student values(null,180403199,'18级大数据2班','小红','女','13435022217','武汉市武昌区水果湖街道','3区2号楼519寝',10);
select * from Student
2. 学生信息管理页面-查询 (后端)
2.1 Student实体类
第一步:在entity包里新建class,命名为Student,该实体类对应数据库中Student表
第二步:在实体类中创建与数据库中一一对应的字段
private Integer id;
private String StudentNum;
private String StuClass;
private String StudentName;
private String sex;
private String PhoneNum;
private String Address;
private String SchoolAddress;
private Integer Rid;
private StudentRecord studentRecord;
private Integer Rid; //这两个字段是之后学生表和学生档案表联表查询时会应用到,相当于在学生表中设立一个档案表的外键
private StudentRecord studentRecord;
第三步:无参和有参的构造方法
在Student类中右键 -->Source -->Generate Constructor using Fields
点击Select All选择全部 -->Generate (此为构造有参)
点击Deselect All选择全部 -->Generate (此为构造无参)
有参无参构造完毕,其中有参的作用是为创建好的字段实例化,无参的作用是默认调用有参方法
第四步: Get/Set 方法构造
在Student类中右键 -->Source --> Generate Getters and Setters
点击Select All选择全部 -->Generate
Get/Set方法构造完毕
第五步: 创建toString方法
在Student类中右键 -->Source --> Generate toString()
toString方法构造完毕
toString方法是用来返回原生数据类型的 String 对象值,用于输出报错信息
2.2 StudentController类
StudentController类中创建增删改查的方法
下面这些方法均放在public class StudentController{}内
// 声明变量
@Autowired // 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,每一个Controller类中都要加上
private StudentService studentService; //引入Service类
// 1.查询全部学生的方法
// 只返回数据的方法
@RequestMapping("selectStudentData")
@ResponseBody
public PageInfo<Student> selectAllStu(
@RequestParam(name = "pageNum", defaultValue = "1", required = false) Integer pageNum,
@RequestParam(name = "pageSize", defaultValue = "20", required = false) Integer pageSize) {
// 1.开启分页
PageHelper.startPage(pageNum, pageSize);
// 2.执行查询语句
List<Student> list = studentService.selectAllStu();
// 3.封装pageinfo类
PageInfo<Student> pageInfo = new PageInfo<Student>(list);
return pageInfo;
}
// 只返回页面的方法
@RequestMapping("selectStuView")
public ModelAndView selectUserView() {
ModelAndView mav = new ModelAndView();
mav.setViewName("student-list");
return mav;
}
// 2.添加学生信息
@RequestMapping("insertStu")
@ResponseBody
public ModelAndView insertStu(Student student) {
ModelAndView mav = new ModelAndView();
int flag = studentService.insertStu(student);
if (flag == 0) {
// 添加失败返回本页面
mav.setViewName("student-add");
} else {
// 返回用户列表并查询数据
mav = selectUserView();
}
return mav;
}
// 3.修改学生信息(根据id查询学生信息用来修改)
@RequestMapping("/updateStu")
@ResponseBody
public ModelAndView updateStu(Integer id) {
// 1.获取要修改的信息
Student student = studentService.selectStudentById(id);
// 2.跳转到修改页面
ModelAndView mav = new ModelAndView();
mav.setViewName("student-update");
mav.addObject("student", student);
return mav;
}
// 3.1修改学生信息并且返回信息页面
@RequestMapping("/updateStuData")
public ModelAndView updateStuData(Student student) {
// 1.获取要修改的信息
int flag = studentService.updateStuData(student);
// 2.跳转到对应页面
ModelAndView mav = new ModelAndView();
if (flag > 0) {// 修改成功,跳转到信息页面
mav.setViewName("student-list");
} else {// 修改失败,继续回到修改页面
mav.setViewName("student-update");
}
return mav;
}
// 4.批量删除学生信息
@RequestMapping("/deleteStudent")
@ResponseBody
public boolean deleteStudent(Integer[] ids) {
return studentService.deleteStudent(ids);
}
// 5.单行删除产品
@RequestMapping("/deleteStudentOne")
@ResponseBody
public int deleteStudentOne(Integer id) {
return studentService.deleteStudentOne(id);
}
这两行放在public class StudentController{}外
@Controller
@RequestMapping("StudenInfo")
**@Controller :**使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法。被Controller标记的类就是一个控制器,这个类中的方法,就是对数据相应的处理。
**@RequestMapping:**是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径 例如:http://localhost:8080/ssm/StudenInfo。用于方法上,表示该方法的所有请求都是以该地址作为次路径
例如:http://localhost:8080/ssm/StudenInfo/selectStuView
**@ResponseBody:**使用它标记的方法表示其中的操作会像前端传递具体的数据,如果仅仅是将页面返回前前端则不需要
按照顺序写,不要一次全复制,先把查询做好
2.3 StudentService接口
该接口上联Controller,下接ServiceImpl实体类,作为服务层起到存贮方法方便引用的功能
在Controller类中引入时出现红色下划线时,光标放在红色下划线上,点击Create method,即可在Service接口中创建方法
package com.yzw.service;
import java.util.List;
import com.yzw.entity.Student;
public interface StudentService {
List<Student> selectAllStu();
int insertStu(Student student);
Student selectStudentById(Integer id);
int updateStuData(Student student);
boolean deleteStudent(Integer[] ids);
int deleteStudentOne(Integer id);
Student getStudentDetailById(Integer id);
}
2.4 StudentServiceImpl实体类
该类上接Service接口中的方法,下接StudenDao接口中操作SQL语句的方法,起到传递方法值的作用
创建好该类后首先标注@Service注解,然后与Service接口建立 implements 联系,之后在方法内引入StudenDao类
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
在StudentServiceImpl出现红色下划线时,光标放在红色下划线上,点击Add method,即可在ServiceImpl类中创建方法
然后 return返回到StudenDao中的方法
package com.yzw.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yzw.dao.StudentDao;
import com.yzw.entity.Student;
import com.yzw.service.StudentService;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public List<Student> selectAllStu() {
// TODO Auto-generated method stub
return studentDao.selectAllStu();
}
@Override
public int insertStu(Student student) {
// TODO Auto-generated method stub
return studentDao.insertStu(student);
}
@Override
public Student selectStudentById(Integer id) {
// TODO Auto-generated method stub
return studentDao.selectStudentById(id);
}
@Override
public int updateStuData(Student student) {
// TODO Auto-generated method stub
return studentDao.updateStuData(student);
}
@Override
public boolean deleteStudent(Integer[] ids) {
// TODO Auto-generated method stub
for (int i = 0; i < ids.length; i++) {
studentDao.deleteStudent(ids[i]);
}
return true;
}
@Override
public int deleteStudentOne(Integer id) {
// TODO Auto-generated method stub
return studentDao.deleteStudentOne(id);
}
2.5 StudenDao接口
StudenDao接口中创建SQL语句,实现直接对数据库中数据的增删改查
@Select @Update @Delete 是mybatis中的注解功能。能够实现对SQL语句的快速操作,从而不需要在XML文件中额外配置
// 1.根据id查询学生记录
@Select("select * from Student where id = #{id}")
Student selectStudentById(Integer id);
// 2.修改学生记录
@Update("update Student set StudentNum=#{StudentNum},StuClass=#{StuClass},StudentName=#{StudentName},sex=#{sex},PhoneNum=#{PhoneNum},Address=#{Address},SchoolAddress=#{SchoolAddress} where id=#{id}")
int updateStuData(Student student);
// 3.多行删除语句
@Delete("delete from Student where id=#{id}")
int deleteStudent(int id);
// 4.单行删除语句
@Delete("delete from Student where id=#{id}")
int deleteStudentOne(Integer id);
按顺序一个个的写,先把查询做好,再做后面的,不要一下全都复制过去
3.学生信息管理页面-查询(前端)
3.1 前端页面设计
3.2 aside页面
该页面作为菜单页面需要设置按钮传值,从而在右侧的显示页显示相应的页面
<li id="admin-product">
<a href="${pageContext.request.contextPath}/StudenInfo/selectStuView"><!-- 设置URL -->
<i class="fa fa-circle-o"></i>学生基本信息管理
</a>
</li>
3.3 Student-list页面
1.设置分页默认的初始值
var $pageNum = 1;//当前页
var $pageSize = 5;//每页的数量
var $pageInfo;//当前分页信息
$(document).ready(function() {
// 选择框
$(".select2").select2();
//刷新页面
getUserPageInfo($pageNum,$pageSize);
// WYSIHTML5编辑器
$(".textarea").wysihtml5({
locale : 'zh-CN'
});
});
ready()方法是进入一个页面最先执行的js方法,所以要把显示页面信息的方法放在这里,这样每次刷新页面,查询的值就会刷新
3.创建动态添加表格方法,用.each方法创建table和td用于放置数据集合
//动态添加表格
function addTable(pageInfo){
$("tbody").empty();//清空
//数据集合
$.each(pageInfo.list,function(index,StudenInfo){
$("tbody").append("<tr><td><input class='checkItem'type='checkbox'></td>"+
"<td>"+ StudenInfo.id +"</td>"+
"<td>"+ StudenInfo.studentNum +"</td>"+
"<td>"+ StudenInfo.stuClass +"</td>"+
"<td>"+ StudenInfo.studentName +"</td>"+
"<td>"+ StudenInfo.sex +"</td>"+
"<td>"+ StudenInfo.phoneNum +"</td>"+
"<td>"+ StudenInfo.address +"</td>"+
"<td>"+ StudenInfo.schoolAddress +"</td>"+
"<td class='text-center'>"+
"<button type = 'button' class='detailStudent btn bg-olive btn-xs'>详情</button>"+
"<button type = 'button' οnclick='update("+StudenInfo.id+")' class='btn bg-olive btn-xs'>修改</button>"+
"<button type = 'button' οnclick='deleteUserOne("+StudenInfo.id+")' class='btn bg-olive btn-xs' >删除</button>"+
"</td>"+
"</tr>");
})
}
这里的StudenInfo就是Controller类中的**@RequestMapping(“StudenInfo”)**
后面引用的id、studentNum为Student实体类中实例化之后的有参构造,不是数据库中的原字段,所以首字母是小写的,因此可以被引用到function中
4.利用ajax动态传值刷新页面,这种方法好处在于当数据改变后只会刷新数据,不会把整个页面刷新,大大提升了运行速度
//ajax动态传值刷新页面
function getUserPageInfo(pageNum,pageSize){
//获取页面数据
$.ajax({
url:$webName + "/StudenInfo/selectStudentData",
type:"post",
data:"pageNum="+pageNum+"&pageSize="+pageSize,
success:function(pageInfo){
//动态生成表格
addTable(pageInfo)
//动态生成分页组件
addPageInfo(pageInfo);
//当前分页信息
$pageInfo=pageInfo;
}
});
}
5.获取数据后,动态生成分页组件,通过选择不同的数字,显示数据的多少
//获取数据后,动态生成分页组件
function addPageInfo(pageInfo){
$("#pageDiv").empty();
$("#pageDiv").append("总共"+pageInfo.pages+"页,共"+pageInfo.total+"条数据。每页"+
"<select class='form-control' id='pagechange' value='5'>"+
"<option value='5'>5</option>"+
"<option value='10'>10</option>"+
"<option value='20'>20</option>"+
"<option value='50'>50</option>"+
"<option value='100'>100</option>"+
"</select> 条"
);
//使用jquery的change事件绑定下拉框
console.log($pageSize);
$("#pagechange").val($pageSize);
$("#pagechange").change(function(){
$pageSize = $(this).val();
getUserPageInfo($pageNum,$pageSize);
})
$("#pageUl").empty();
$("#pageUl").append("<li><a href='#' class='first' aria-label='Previous'>首页 </a></li>"+
"<li><a href='#' class='pre'>上一页</a></li>"
);
$.each(pageInfo.navigatepageNums,function(index,num){
if(num==pageInfo.pageNum){
//判断当前页
$("#pageUl").append("<li class='active'><a href='#' class='current'>"+ num +"</a></li>");
}else{
$("#pageUl").append("<li><a href='#' class='current'>"+ num +"</a></li>");
}
})
$("#pageUl").append("<li><a href='#' class='next'>下一页</a></li>"+
"<li><a href='#' class='last' aria-label='Previous'>尾页 </a></li>"
);
}
//分页
$(document).on("click",".first",function(){
$pageNum = 1;
getUserPageInfo($pageNum,$pageSize);
});
$(document).on("click",".pre",function(){
if($pageNum > 1){
$pageNum = $pageNum - 1;
}
getUserPageInfo($pageNum,$pageSize);
});
$(document).on("click",".current",function(){
$pageNum = $(this).text();
getUserPageInfo($pageNum,$pageSize);
});
$(document).on("click",".next",function(){
if($pageNum < $pageInfo.pages){
$pageNum = $pageNum + 1;
}
getUserPageInfo($pageNum,$pageSize);
});
$(document).on("click",".last",function(){
$pageNum = $pageInfo.pages;
getUserPageInfo($pageNum,$pageSize);
});
最后呈现的效果是这样的: