Struts2.5+Hibernate5.8.0实现的学生成绩管理系统
2018-02-08 11:03
537 查看
Struts2.5+Hibernate5.8.0实现的学生成绩管理系统(Javaweb项目)
该项目使用的Tomcat版本为9.0.2,JDK版本为jdk1.8.0_91,数据库为MySQL(PS:该项目前端不好看,关于struts2的配置可参照struts2的配置问题)(1)实现功能:
实现了登陆验证,必须登陆才能访问其它页面
可对数据进行分页
实现对成绩的复杂查询,如成绩等级,分数等,并且实现排序
可以将数据导出到excel表下载
实现数据库的备份和恢复
实现对输入信息的校验.
(2)运行效果以及数据库内容:
登陆界面:
查看学生信息界面:
添加学生信息界面:
数据库:
(3)关于项目的各种XML文件的配置:
a) web.xml(放在WEB-INF目录下)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>student</display-name> <description>MySql数据库连接池</description> <resource-ref> <res-ref-name>students</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> <filter> <filter-name>login</filter-name> <filter-class>com.mdy.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>login</filter-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.action</url-pattern> <url-pattern>*.do</url-pattern> </filter-mapping> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 使用标签库所需的配置 --> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri> <taglib-location>/WEB-INF/c.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri> <taglib-location>/WEB-INF/fmt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/sql</taglib-uri> <taglib-location>/WEB-INF/sql.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/x</taglib-uri> <taglib-location>/WEB-INF/x.tld</taglib-location> </taglib> </jsp-config> </web-app>
b) struts.xml(放在scr目录下)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <!-- 指定需要Struts2处理的请求后缀 --> <constant name="struts.action.extension" value="do,action"></constant> <!-- 设置浏览器是否缓存静态内容,开发阶段应关闭,生产阶段打开,默认为打开 --> <constant name="struts.serve.static.browserCache" value="false"></constant> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认为false,开发阶段应打开 --> <constant name="struts.configuration.xml.reload" value="true"></constant> <!-- 开发模式下使用,可以打印出更详细的错误信息 --> <constant name="struts.devMode" value="true"></constant> <!-- action全部用注解进行配置 --> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <!-- 是否开启动态方法调用 --> <package name="default" namespace="/JSP" extends="struts-default"> <global-results> <result name="error">/JSP/error.jsp</result> </global-results> <global-allowed-methods>add,execute,search,jump,del,revise,login</global-allowed-methods> <action name="login" class="com.mdy.action.Login" method="login"> <result name="success">/JSP/add_student.jsp</result> <result name="login_error">/JSP/login.jsp</result> </action> <action name="add" class="com.mdy.action.AddAction" method="add"> <result name="success">/JSP/add_success.jsp</result> <result name="error_exist">/JSP/add_error_exist.jsp</result> <result name="input">/JSP/add_student.jsp</result> </action> <action name="search" class="com.mdy.action.GetData" method="search"> <result name="success">/JSP/ViewData.jsp</result> </action> <action name="jump" class="com.mdy.action.GetData" method="jump"> <result name="success">/JSP/ViewData.jsp</result> </action> <action name="del" class="com.mdy.action.ReviseData" method="del"> <result name="success">/JSP/del_success.jsp</result> </action> <action name="revise" class="com.mdy.action.ReviseData" method="revise"> <result name="success">/JSP/revise_success.jsp</result> </action> </package> </struts>
c) hibernate-cfg-xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF-8&useSSL=false</property> <property name="connection.username">admin</property> <property name="connection.password">admin</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">10</property> <!--jdbc.fetch_size是指Hibernate每次从数据库中取出并放到JDBC的Statement中的记录条数。Fetch Size设的越大,读数据库的次数越少,速度越快, Fetch Size越小,读数据库的次数越多,速度越慢--> <property name="jdbc.fetch_size">100</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">false</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <!-- <property name="hibernate.search.default.directory_provider">filesystem</property> <property name="hibernate.search.default.indexBase">target/indexes</property> --> <mapping resource="com\mdy\bean\User.hbm.xml" /> <mapping resource="com\mdy\bean\Student.hbm.xml" /> </session-factory> </hibernate-configuration>
(4)功能实现:
1.登陆验证实现返回顶部
(a)实现方法:采用了servlet的过滤器
(b)具体实现:
a) 过滤器起作用在web.xml的配置:
<filter> <filter-name>login</filter-name> <filter-class>com.mdy.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>login</filter-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.action</url-pattern> <url-pattern>*.do</url-pattern> </filter-mapping>
(PS:最好将该过滤配置写在struts2的过滤上面,不然过滤器可能会不起作用)
b) 过滤器的类:
@Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) arg0; HttpServletResponse response = (HttpServletResponse) arg1; HttpSession session = request.getSession(); String path = request.getServletPath();//获得要访问的页面的名字 String flag = (String) session.getAttribute("flag");//flag为识别是否已经登陆过的session System.out.println(flag+path); if (path == null || path.equals("/JSP/login.jsp")|| path.equals("/JSP/login.action")) {//不能过滤掉登陆界面和动作 arg2.doFilter(arg0, arg1); } else {//登陆失败一律采用页面重定向到登陆界面 if(flag==null) { request.setAttribute("msg", "用户未登陆!!"); RequestDispatcher rd = request.getRequestDispatcher("/JSP/login.jsp"); rd.forward(request, response); } else { if (flag.equals("登陆成功")) { arg2.doFilter(arg0, arg1); } else { request.setAttribute("msg", "请登陆"); RequestDispatcher rd = request.getRequestDispatcher("/JSP/login.jsp"); rd.forward(request, response); } } } } }
2.分页功能实现返回顶部
(a)实现方法:使用一个bean:PageBean,储存要显示的数据和当前页面的信息,将储存在session中。数据库的操作采用了Hibernate的HQL语句和标准查询API,详细实现在第三点的复合搜索加排序的实现中
(b)具体实现:
a) PageBean的实现bean类:
public class Page<T>{ private int pageNum;//当前页面 private int pageTotal;//总页面 public static final int pageMax = 15;//页面的数据量 private long totalData;//数据总数 private int start;//分页栏的起始页 private int end;//分页栏的终止页 private List<T> list;//显示在当前页面的数据 //省略一部分getter和setter //每次页码变化就对start和end进行修改 public void setPageNum(int pageNum) { this.pageNum = pageNum; this.start=pageNum-2; if(this.start<=0) { this.start=1; } this.end=this.start+4; if(this.end>pageTotal) { this.end=pageTotal; } } //设置总数据量时进行总页码计算 public void setTotalDate(long totalData) { int t = 1; if ((int)totalData % pageMax== 0) { t = 0; } pageTotal = (int) (totalData / pageMax + t); this.totalData = totalData; } }
b) 页面跳转动作的实现方法:
public String jump() throws ServletException, IOException { HttpServletRequest request = ServletActionContext.getRequest(); HttpSession session = request.getSession(); pagebean = (Page<Student>) session.getAttribute("pagebean");//得到当前页面的pagebean com.mdy.dao.GetData gd = new com.mdy.dao.GetData(); //判断页码是否越界 if (search.get_pageNum() > pagebean.getPageTotal()) { search.set_pageNum(pagebean.getPageTotal()); ; } pagebean.setList(gd.getData(Page.pageMax, search.get_pageNum(),(String)session.getAttribute("search_sql")));//得到当前页面的搜索条件 pagebean.setPageNum(search.get_pageNum()); session.setAttribute("pagebean", pagebean); return SUCCESS; }
c) 分页栏的JSP:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <div align="center"> <form action="jump.action" name="page"> <ul class=page> <li><a href="jump.action?_pageNum=1">首页</a> <li><a <c:if test="${_pageNum-1 gt 0}">href="jump.action?_pageNum=${_pageNum-1}"</c:if>>上一页</a> <input style="width: 30px;" name="_pageNum" value="${pagebean.pageNum}"><!-- 跳转页面输入框 --> <!-- 当要显示页面均大于1时 显示[...]--> <c:if test="${pagebean.start>1}"> <li>[...] </c:if> <!-- 使用JSTL的foreach显示五页 --> <c:forEach var="i" begin="${pagebaen.start}" end="${pagebean.end}"> <c:if test="${i >= pagebean.start && i <= pagebean.end}"> <a <c:if test="${i != pagebean.pageNum}">href="jump.action?_pageNum=${i}"</c:if>>[${i}]</a> </c:if> </c:forEach> <!-- 当要显示页面均小于最大页面2时 显示[...]--> <c:if test="${pagebean.end<pagebean.pageTotal}"> <li>[...] </c:if> <li><button type="submit" onclick="return CheckPage(page)">跳转</button><!-- 使用JS进行输入框内容校验 --> <li><label>${pagebean.pageNum}/${pagebean.pageTotal}</label> <li><a <c:if test="${_pageNum+1 <= pagebean.pageTotal}">href="jump.action?_pageNum=${pagebean.pageNum+1}"</c:if>>下一页</a> <li><a href="jump.action?_pageNum=${pagebean.pageTotal}">尾页</a> </ul> </form> </div>
3.复合搜索加排序返回顶部
(a)实现方法:使用了Hibernate的HQL和标准查询API进行查询,将搜索框的数据按格式拼成字符串传递给数据库操作类进行操作,并将其保存在session里让分页的页面跳转使用。
(b)具体实现:
a) 数据库操作类:
private long i;//总数据量 //得到学生成绩 /* * pageMax 页面显示的最多数据 * pageNum 页码 * str 搜索条件 * */ @SuppressWarnings({ "unchecked", "unused", "deprecation" }) public List<Student> getData(int pageMax, int pageNum, String str) throws HibernateException { List<Student> student = null; Configuration configuration = new Configuration().configure(); SessionFactory factory = configuration.buildSessionFactory(); Session session = factory.getCurrentSession(); Transaction transaction = session.beginTransaction();//事务开始 //判断str是否为空或需不需要搜索 if (str == null||str.equals("%% none per 0 100 asc id %%")) { i = ((long)session.createQuery("select count(*) from Student").uniqueResult());//得到数据总数 student = session.createQuery("from Student") .setFirstResult((pageNum - 1) * pageMax)//设置搜索得到的数据从哪里开始返回,0为第一条数据 .setMaxResults(pageMax).list();//设置返回的数据总量 } else { String[] string = str.split(" "); student = session.createCriteria(Student.class).add(Restrictions.like("name", string[0]))//模糊查询姓名的语句 .add(Restrictions .or(string[1].charAt(0) == 'n' ? Restrictions.isNotNull("level") : Restrictions.like("level", string[1].charAt(0))) .add(Restrictions.like("level", string[1].charAt(0))))//成绩等级的条件语句 .add(Restrictions.between(string[2], Double.parseDouble(string[3]), Double.parseDouble(string[4])))//成绩范围的查询语句 .addOrder(string[5].equals("asc") ? Order.asc(string[6]) : Order.desc(string[6]))//升降序的查询语句 .add(Restrictions.like("id", string[7]))//模糊查询学号的语句 .setFirstResult((pageNum - 1) * pageMax) .setMaxResults(pageMax) .list(); i = (long) session.createCriteria(Student.class).add(Restrictions.like("name", string[0])) .add(Restrictions .or(string[1].charAt(0) == 'n' ? Restrictions.isNotNull("level") : Restrictions.like("level", string[1].charAt(0))) .add(Restrictions.like("level", string[1].charAt(0)))) .add(Restrictions.between(string[2], Double.parseDouble(string[3]), Double.parseDouble(string[4]))) .addOrder(string[5].equals("asc") ? Order.asc(string[6]) : Order.desc(string[6])) .add(Restrictions.like("id", string[7])).list().size();//得到数据总数 } transaction.commit();//事务提交,会自动关闭由getCurrentSession()得到的session,而openSession()得到的则不会 return student; }
4.数据导出成excel并下载返回顶部
(a)实现方法:直接使用JSP实现,使用了外部工具包poi-3.17.jar创建excel表格,并且使用了JSTL的sql标签(其实没必要),使用文件操作流时使用了response的OutputStream,需要在使用OutputStream前调用response.reset(),清空之前输出流的静态内容,否则会出错。
(b)具体实现:
a) ExcelExport.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="com.mdy.bean.Student"%> <%@page import="java.util.SortedMap,java.io.OutputStream,java.io.FileOutputStream,java.io.File,org.apache.poi.hssf.usermodel.HSSFRow,org.apache.poi.hssf.usermodel.HSSFSheet,org.apache.poi.hssf.usermodel.HSSFWorkbook"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <sql:setDataSource url="jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf-8&useSSL=false" driver="com.mysql.jdbc.Driver" user="admin" password="admin" var="StudentDataBase" /> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <link href="main.css" rel="stylesheet" type="text/css"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>导出信息</title> </head> <% HSSFWorkbook wb = new HSSFWorkbook();//创建工作簿对象 HSSFSheet sheet = wb.createSheet("学生成绩");//创建一个表 int i = 0; HSSFRow row = sheet.createRow(i++); row.createCell(0); row.createCell(1); row.createCell(2); row.createCell(3); row.createCell(4); row.createCell(5); row.createCell(6); row.createCell(7); row.getCell(0).setCellValue("学号"); row.getCell(1).setCellValue("姓名"); row.getCell(2).setCellValue("语文成绩"); row.getCell(3).setCellValue("数学成绩"); row.getCell(4).setCellValue("英语成绩"); row.getCell(5).setCellValue("作业成绩"); row.getCell(6).setCellValue("平均分"); row.getCell(7).setCellValue("成绩等级"); %> <!-- 使用了JSTL的sql标签 --> <sql:query var="res" sql="select * from student_score" dataSource="${StudentDataBase}"></sql:query> <!-- 使用JSTL的foreach,res为检索后得到的数据集合,res.rows为一个SortMap对象 --> <!-- 为了在JSP里面调用re,需要将其储存在request域里面 --> <c:forEach items="${res.rows}" var="re"> <c:set value="${re}" var="r" scope="request" /> <% row = sheet.createRow(i++); SortedMap sm = (SortedMap) request.getAttribute("r"); row.createCell(0); row.createCell(1); row.createCell(2); row.createCell(3); row.createCell(4); row.createCell(5); row.createCell(6); row.createCell(7); row.getCell(0).setCellValue((String) sm.get("学号")); row.getCell(1).setCellValue((String) sm.get("姓名")); row.getCell(2).setCellValue(String.valueOf(sm.get("语文成绩"))); row.getCell(3).setCellValue(String.valueOf(sm.get("数学成绩"))); row.getCell(4).setCellValue(String.valueOf(sm.get("英语成绩"))); row.getCell(5).setCellValue(String.valueOf(sm.get("作业成绩"))); row.getCell(6).setCellValue(String.valueOf(sm.get("平均分"))); row.getCell(7).setCellValue(String.valueOf(sm.get("成绩等级"))); %> </c:forEach> <% response.reset(); OutputStream output = response.getOutputStream();//因为只能打开一个输出流,为了得到reponse的OutputStream,必须将reponse重置 //让浏览器识别其为下载文件的设置 response.setHeader("Content-disposition", "attachment; filename=poi.xls"); response.setContentType("application/msexcel"); //输出excel表格 wb.write(output); output.close(); wb.close(); %> <body> </body> </html>
5.数据备份和恢复返回顶部
(a)实现方法:使用了mysql自带的备份和恢复工具,这里笔者使用绝对路径访问,可通过配置path实现直接访问。通过得到mysql工具向控制台输出数据,将其储存在文件里面实现备份,恢复也是同理
(b)具体实现:
a) 备份的实现
Runtime rt = Runtime.getRuntime(); //调用mysql的备份工具的命令 Process child = rt.exec("g:\\mysql-5.7.20-winx64\\bin\\mysqldump -h localhost -uadmin -padmin student"); // 设置导出编码为utf-8 InputStream in = child.getInputStream();// 控制台的输出信息作为输入流 InputStreamReader xx = new InputStreamReader(in, "utf-8"); // 设置输出流编码为utf-8 String inStr; StringBuffer sb = new StringBuffer(""); String outStr; // 组合控制台输出信息字符串 BufferedReader br = new BufferedReader(xx); while ((inStr = br.readLine()) != null) { sb.append(inStr + "\r\n"); } outStr = sb.toString(); //获得备份地址的绝对路径 FileOutputStream fout = new FileOutputStream(session.getServletContext().getRealPath("/SQL")+"/student.sql"); OutputStreamWriter writer = new OutputStreamWriter(fout, "utf-8"); writer.write(outStr); writer.flush(); in.close(); xx.close(); br.close(); writer.close(); fout.close();
a) 恢复的实现:同理,只是换成向控制台输入信息
Process process = runtime.exec( "g:\\mysql-5.7.20-winx64\\bin\\mysql -hlocalhost -uadmin -padmin --default-character-set=utf8 student");
6.输入校验的实现返回顶部
(a)实现方法:使用了JS实现以及struts2的校验器
(b)具体实现:
a) JS的代码:
function validate_required_name(field) { var re_name = /^[\u4e00-\u9fa5]+$/ with (field) { if (value == null || value == "") { document.getElementById("_name").innerHTML = "名字不能为空" return false } else { if (re_name.test(value)) { return true } else { document.getElementById("_name").innerHTML = "名字必须为中文" return false } } } } function validate_required_score(field) { var num = /^[0-9]+.?[0-9]*$/ with (field) { if(value==null||value==""){ return false } else{ if(num.test(value)&&0<=value&&value<=100){ return true } else{ return false } } } } function validate_form(thisform) { with (thisform) { if (validate_required_name(name) == false) { name.focus() return false } if (validate_required_score(chinese) == false) { chinese.focus() document.getElementById("_chinese").innerHTML = "成绩必须在0到100之间" return false } if (validate_required_score(math) == false) { math.focus() document.getElementById("_math").innerHTML = "成绩必须在0到100之间" return false } if (validate_required_score(english) == false) { english.focus() document.getElementById("_english").innerHTML = "成绩必须在0到100之间" return false } if (validate_required_score(homework) == false) { homework.focus() document.getElementById("_homework").innerHTML = "成绩必须在0到100之间" return false } } }
b) struts2的校验器:(使用正则表达式时param的name值为regexExpression时才会起作用)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"> <validators> <field name="student.name"> <field-validator type="requiredstring"> <message>姓名必须输入</message> </field-validator> <field-validator type="regex" > <param name="regexExpression"><![CDATA[(^[\u4e00-\u9fa5]{1,6}$)]]></param> <message>姓名必需是长度不超过6,且必须是汉字</message> </field-validator> </field> <field name="student.chinese"> <field-validator type="double"> <param name="min">0</param> <param name="max">100</param> <message>成绩必须在0至100之间</message> </field-validator> </field> <field name="student.math"> <field-validator type="double"> <param name="min">0</param> <param name="max">100</param> <message>成绩必须在0至100之间</message> </field-validator> </field> <field name="student.english"> <field-validator type="double"> <param name="min">0</param> <param name="max">100</param> <message>成绩必须在0至100之间</message> </field-validator> </field> <field name="student.homework"> <field-validator type="double"> <param name="min">0</param> <param name="max">100</param> <message>成绩必须在0至100之间</message> </field-validator> </field> <field name="student.id"> <field-validator type="requiredstring"> <message>学号必须输入</message> </field-validator> <field-validator type="regex"> <param name="regexExpression"><![CDATA[(\d{6})]]></param> <message>学号必须是6位的数字</message> </field-validator> </field> </validators>
相关文章推荐
- 【转】 [C/OC的那点事儿]NSMutableArray排序的三种实现(依赖学生成绩管理系统).
- 学生成绩管理系统课程设计(C语言,链表实现)
- [置顶] c语言文件读取 学生成绩管理系统的设计与实现
- C语言实现---学生成绩管理系统
- 用文件实现学生成绩管理系统
- Python简单实现学生成绩管理系统
- 类实现学生成绩管理系统
- C语言实现学生成绩管理系统
- 链表《5》使用链表实现学生成绩管理系统
- 使用C++结合文件操作和链表实现学生成绩管理系统
- shell实现学生成绩管理系统
- 简单学生成绩管理系统(Java实现)
- 基于C语言实现学生成绩管理系统
- shell 编程实验--实现学生成绩管理系统
- Java GUI实现学生成绩管理系统
- c++链表实现学生成绩管理系统(简易版)
- 用链表写的学生管理系统 成绩的录入与查询都已经是实现了
- shell编程实现学生成绩管理系统
- 学生成绩管理系统链表实现
- java编程实现学生成绩管理系统,采用顺序存储结构