本次课程的作品为“学生选课系统”,选此课题初衷是毕竟自己作为一个学生来说最为贴近的就是学生选课系统,平常都是作为一个用户来使用这个系统,没有什么深入的了解其中的实现原理,所以抱着试一试的看法希望自己可以独立开发出一个简单美观的小项目来。
一、设计之初
首先,当然是选用什么样的技术来实现这个项目。目前所掌握的可以应用的无非是jsp,java swing亦或者是c#,但是c#目前还在学习中,甚至数据库还没学会怎么来连接,选择他并不是什么明智之举啊!Java swing倒是很早就有接触,但是就目前掌握的知识来说,要想符合人机交互的要求的美观来说,个人觉得其扩展性实在是有限,要想成功做好的这个小项目,java swing的美化实在是要下不少的功夫,还有可能收效甚微。所以jsp和java的结合成为了最后的选择。“工欲善其事,必先利其器”,选择了开发语言,自然也就缩小了对开发工具的选择范围,曾经听说好多企业都开始选用IntelliJ IDEA ,于是前阶段尝试使用了一下,确实感受到了他的强大但是有好多地方还是用不明白,所以还是使用最为熟悉的eclipse,出现问题也好接解决,数据库方面选用mysql,SQLyog作为数据库的图形化界面。
刚一开始就遇到个大麻烦,eclipse安装不上、mysql安装用不了、tomcat不会配置,写好的程序连接不上数据库、jar包明明按照网上安的还是出现ClassNotFoundException错误……,诸如此类跟工具使用有关的问题层出不穷,实在是虐心,不得不承认第一次做项目的经验少带来的麻烦直接影响了我的心情,尤其是那种明明是按照百度上的说的照做还是出错的情况,真的恨不得在淘宝买一个草草了事算了。但是幸运的是到最后选择了坚持下去,尽管痛苦但是学习到了许多,把一切的工具、环境搞定了之后。终于可以开始了探索之路。
按照软件工程的概念来说,先进行需求分析,那我也开始进行分析这个项目的怎么实现的。首先,就按照学校的教务系统来说,可以学生登录,教师登录,管理员登录,他们都是通过学号或者教师号来进行登录的,那么就得一改我们平常上课的概念使用用户名登录,在这一点上应用到该项目是合理的!其次,数据库里至少要有学生的信息列表,老师的信息列表,课程的列表,他们之间是什么关系呢?学生具有姓名,学号,学院等等属性,具有选课上课的行为,教师同样具有姓名,教师号,学院等等属性,具有上课和给学生成绩的行为,属性可以在数据库表里实现,那么这个选课,上成绩在哪实现呢?我想还需要一个表来连接这三个属性表,同时加上成绩一栏。这样在连接的同时还可以实现对成绩的修改和查询。这个连接表学生学学号,教师号,课程号,以及成绩。
二、实施过程
首先要写一个登陆界面,看过许多的网站登录界面,感觉都是很简约的风格,并不是十分的复杂,但是当我打开页面源代码的时候,发现自己还是想简单了,自己的知识储备仅限于能看懂大体的块布局设计,具体的细节还是有些难度的,毕竟css并没有那么系统的学习过。迫于能力的约束,我也只能选用简约风格的登录界面,但是我觉得简约也可以很漂亮,简约也可以做到不简单。所以,我选择了以一个郊外落日昏黄,半边天彩虹图片为背景,暖色为主调,画面中央的“User Login” logo ,底下为用户“id”和“密码”的输入框,与背景色呼应的登录按钮,“忘记密码”的超链接,点击直接alert“通知管理员”,没有设置注册功能和按钮,因为我想注册的实现是通过管理员对数据库的表的增加,而不是学生和老师都有权限进行注册和修改的,就比如我刚开学的时候我的学号和密码都是老师告诉的,并不是我自己注册上去的。所以说在这个方面我考虑的较为全面。为了让这个界面看起来更像是一个B/S应用的界面,而不是像一个简简单单的初学者学的前端界面,我又在左下角增加了版本号,在右下角添加的“联系我们”“法律咨询”“隐私政策”等超链接,并且设置了超链接鼠标附上变色以及点击变色,虽然功能没有实现(具体要实现什么功能我也不太清楚),但是可以使整个界面看起来功能性更加丰满。登陆界面的后台处理则用到了servlet,从页面获取的id值和密码先进性判断是什么类型的账号,如果是管理员账号的话,按照预先的设计则要对数据库的三个实体表进行再页面的上的输出。这个过程着实为难到了我,因为从数据库查到的表的数据都不是单一的数据,都是一个集合一个集合的,对!集合!这可真的提醒了我,于是我想到了使用List集合,再写一个javaBean作为泛型,把每次查询得出的数据先存到集合里再说。接下来的问题就是怎么完整的把数据打印到jsp页面上呢?想了许久未果后,在网上找到的方法就是在jsp页面使用ForEach()方法,这个方法的有点在不论数据库里的数据是多少,都能实现的相应的动态打印,避免了使用固定列表时数据过多,没有列表来存储显示或者是数据过少留下太多的空列表影响美观。在显示数据列表的jsp页面上,添加“添加”“修改”“删除”的超链接来对表进行操作,当然这都是属于管理员登录的操作,每一个超链接跳转的页面皆不相同“添加”则是将所属的列表所有的数据属性都提取出来,也就是说,要操作的这个列表的有哪些属性,我在添加页面就增加哪些属性的文本栏,然后再后台对相应的数据表内进行插入操作。修改和添加如出一辙,因为当时我考虑到一个可能有多个需要修改的项目,索性就需要的都进行输入,那么在后台的修改操作就变成了全部修改,尽管有些值会和之前的一样。这里从人机交互的角度来衡量的话还是非常有缺陷的,不论怎么样都需要进行输入,着实是降低了用户体验,今后的改进我希望会使用下拉列表框来改善这个弊端。删除相对来说比较简单,只需要在页面输入相应的id,因为他唯一嘛,在后台就可以根据这个id进行全部删除。如此一来,管理员所具有的所有功能操作大致都实现了,其实我还发现的一个弊端,就是在每一次进行的增删改之后,我设计的页面跳转都是从新跳转到登录界面,这样一来就增加了操作的不简便性,后来我又尝试进行直接跳转到管理员的操作界面,发现实际进行增删改操作后的数据并未发生改变。这样的话我就在想为什么没有实现更新,后来我想到了一个方法,算是比较笨的一种吧,就是再写个类,实现对数据库表的查询并输出jsp的类,在每次操作之后都调用这个类,这样一来就应该会解决了。
其次,是学生登录的时候进行的相关操作,首先我需要验证输入的id和密码是不是学生类型的,于是有一个类里面的定义了一个返回值为boolean型的方法,方法内容无非是连接数据库并查询id和密码,和页面传来的的id和密码进行匹配,匹配上就返回真,否则为false再在登陆界面的后台程序中判断返回值是true 或者false ,true的话操作为在课程表内查询这个学生所在的学院的都开了什么课,并且输出到学生登陆后的界面上,这样提供了数据学生才可以进行选课。这个sql语句着实费了我不少功夫,记得数据库考试的时候老师说考两层嵌套循环的sql语句都不多,但是我写的这个写了三个嵌套,到最后还显示了查出不止一条的异常。大致思路如下:先获取页面的id,在Student表中查询这个id表的Sdept(学院),再根据这个Sdept在Student表查询所有的Sno(学号,即为id),再在连接表中查询和查寻出的Sno在同一个栏的Cno(课程号),输出这个Cno的所有数据。好歹是完成了,就当我为此感慨的时候,突然想到为什么不直接根据Sdept在Course表查找呢?不知道会不会奏效,回头试试!学生在得到可选课程的信息后,就可以进行选课了,那么选课的本质其实就是插入数据到表里,记得在成绩表内还有一个属性为教师号,也就是说,同样的一个课程可以有不同的老师来进行授课,一个老师还可以教授多个课程,这样就实现了多对多的关系。我接下来要做的是,学生在选择相应的课程后还需要对成绩表的Tno项进行插入数据,那么学生也不知道这个课程是谁教的啊?所以,我设计了增加一栏学生可以选择授课老师的功能,这个在实际应用上也有所应用,比如我们选课的时候同样的课程时间不是也可以选择老师嘛?所以,我在学生选课界面的下方添加一个文本框,用来和接受学生选择的课程号,增加的Button按钮实现跳转的功能是根据这个课程号(Cno)到教师表里查询和这个Cno匹配的教师信息,由于可能会涉及到隐私,所以在界面上只输出了教师姓名,教师性别,教师号和教师所属学院,这样学生就可以根据老师的信息来进行选老师,选择老师的教师号在后台进行插入操作。在这个部分上,我遇到了一些问题,就是获得数据id 的问题,曾经我以为request.getPramater(“id”);是万能的,不论在哪调用都可以的得到值,其实不然呐!所以我就不得不在登录界面的servlet中添加request.getSession().setAttribute(“id”,id);在学生选课的servlet中添加request.getSession().setAttribute(“Cnoid”,Cnoid); 这样可以实现在servlet中参数传递。然后在学生选老师的servlet中不仅request.getParameter(“Tnoid”,Tnoid),还需要
Request.getSession().getAttribute(“id”);和Request.getSession().getAttribute(“Cnoid”);获取传递来的参数,从而实现对成绩表插入,插入成功后直接对成绩表进行访问并输出,这样看来,之前提出的管理员增删改操作后直接跳转的到显示界面并且是最新数据的想法是可以实现的。如此一来,就完成了学生的选课的操作。
选课操作结束后,学生应该还可以查询成绩,也就是对成绩表的额查询,当然前提是教师对成绩进行了增加,简单的查询表这里就不在做赘述。
最后,就是教师登录系统了,和学生登录如出一辙,先要进行判断是否为教师账号,同样的再写另一个和学生相仿的类里面同样有一个返回值为boolean型的方法,方法的内容同样的用数据库的id和密码来和页面获取到id和密码匹配,原理都一样的,但是登录成功后的处理不一样。教师登录后直接查询成绩表,以登录的id号为条件,这样就可以按照这个条件打输出相应的数据,其实当前的数据就是学生的选课表,上面显示了学生的学号,课程号,这样教师就知道哪些学生选了我的什么课,初始成绩均为0,而后教师可以根据学生号和课程号对学生的成绩上分,以便于学生登录账号的时候可以查看自己选课的成绩。
三、项目优化
所谓项目优化,就是对项目做一个整体的思考,看看有哪些地方还可以改进,还可以进行美化,在哪里还可以提高用户的体验。
1、在登录界面上,整体效果上还可以不需要作过多的更改。但是管理员登录的界面总会觉得有些臃肿,我把三个表的数据都提交到这一个界面上,现在数据库内的数据体量还比较小,操作还是比较简便的,但是数据体量一旦上来了之后,那么这样一个界面内的表格就太大了,想要查看Student表还可以,但是如果要是查看压在下面的Course表,就需要不断的往下翻,翻过了Student,Teacher表才到了Course表,这样的话,用户体验就会相当得差,所以我打算,把每个表都分做一个界面,主界面显示Student表,至于Teacher表和Course表则以超链接的形式来跳转显示。
2、在管理员的增删改的操作以及其他的操作背景上,美观程度很低,如果还是沿用主登录界面的照片背景,那么这个项目在感官上显得有些单调,但是实际上的功能需求都是通过text和button实现,没有过多的控件来充实界面,如果没有独特的背景将会给这个小项目减分,所以我就想可不可以显示动态的界面,自身能力有限又没有说不可以百度,于是就找到了一段前端制作视频学习,按照他的做法做了一个自己的背景。具体效果是这样的,整体的背景颜色是青蓝色,所有的控件都居中,字体为微软雅黑,字体颜色白色,尤其是登录的问候语例如“Hello Classmates”为大字体,在输入文本框显示要输入的数据类型的提示信息,鼠标点击后提示信息消失,选用的这个作为提示信息是因为这样可以使整个界面显得更加简洁,没有多余的东西。除此之外,还有鼠标点击button按钮和输入文本框的时候,控件自动拉长30%,这样的作用旨在提醒当前操作并且增加了用户体验乐趣。
这个背景最为独特的地方在于显示页面的时候会从页面底部弹出大小不一的正方形,以不同的速度,不同的姿势向上飘动直至到顶部停留3秒消失。大致是这样实现的,定义一个ul,在ul中含有十个li,这十个li分别为从左到右的十个,再在css中子类选择器对li进行样式的设计,从而实现动态的页面背景。
3、再对每个界面进行操作的时候发现我如果不想要再执行下去或者想要退出怎么把。于是我就在每个操作界面增加了Back to Home 超链接用来直接返回主界面。在添加一个返回上一层,来实现跳转到上一层,这样可以大大提高操作的简便性,提高了用户的交互体验。
四、心得反思
首先先做一个自我评价,对于这个小项目,首先他是不完美的,他仍然还有许多的缺陷需要被修改,比如在刚刚开始的设计的时候出现的我个人的思维固化,所有的数据输入输出都使用text控件打字输入和列表的格式输出,没有想到使用复选框或者下拉列表框来完成,导致了人机操作步骤较繁琐,偏离了本课程的主旨。在开发完成后我也在想一定可以有优化的方案,只不过我比较熟悉这个方法罢了。在有限的时间的里作东西,我还是要选择我自认为比较有把握的方法,而不是铤而走险去选择什么有风险的方法,当然我说的有风险有点言过其实了,只不过我是对那个方法没有把握能用好。所以只能退而求其次的选择text控件。
这点也是提醒了我,知识的积累真的很重要,不要觉得学了没有用,学到用时方恨少啊!在这里我是真的深有体会了!也许你不经意间的积累,就可以在以后的开发路上少走一些弯路,少踩一些坑,比别人走的远一些!
其次,在整个开发过程中,真的是踩坑无数,日均百度200条,一点都不夸张,知识输入的过程是痛苦的,未经过处理的知识存储在输出同样也是及其痛苦的,在这个阶段我发现我在学习过程中的暴露出的问题,往往都是知其然而不知其所以然。正是通过这一段经历使我的得以反思自己的学习方式和态度是不是应该有所改变啊!学习是一个自我虐待的过程,要自己和自己较劲,才会有所长进,得过且过很难有所建树。想起以前我就是学习总是漫不经心的,看到了简单的大致看一眼就过去了,不会虚心学习,也更不会强往脑袋里面塞。然后就抛到脑后该干啥就干啥了。遇见难的就更可怕了,不会?放到下课看吧!或者之后再看把!然后之后就忘了,这样的拖延症真的很害人,最后导致脑袋里空空如也,需要用的时候当然是怎么也调用不出来啊!因为脑袋里压根没有那个方法或者说属性!
还有,对于经验和知识的匮乏。这个项目但凡是操作都跟数据库挂钩,但凡是跟数据库挂钩都离不开连接数据库。我也是做完才知道有数据库工具类这类东西的存在,而我做到的是每次都连接一次,并且乐此不疲。实在快要蠢哭!其次我还把所有的类都建在一个包中,导致一个包好多的类,尽管我尽量给每个类起名的时候贴近他们的功能,但是还是避免不了在使用的时候两眼一抹黑,挨个类看才明白谁是谁,才找的到!以后再也不会给自己挖这么深的坑了,必定要分包建类!除此之外,在当初建表的时候,我就一直在考虑我的id和密码属性到底要设置成什么类型!Int或者String 一直的犹豫不决,后来干脆中规中矩选用int类型了,但是在后面的从页面获取参数中理所当然的使用了
int id = request.getParameter(“id”); 写完才发现报错了,一直搞不懂错在哪里,后来换成了String id1 = request.getParameter(“id”);才可以编译通过,这可怎么办,获取到的类型值只能是String类型的,那以后我要是和数据匹配也匹配不上啊!尤其在数据库的预处理过程中,st.setInt();用起来真的很尴尬!所以我只好想办法将String类型转化为int id = Integer.valueOf(“id”);这个问题貌似就迎刃而解了,我还在电脑前沾沾自喜,感觉自己终于可以想出来解决办法,就这样的延续这个方法延续下去。直到最后,我的同学问我,我如果把密码设置成有字符串类型怎么办,即使说并不全是数字,可以有字母,空格,或者标点符号吗?我仔细想了想,肯定不可以!我的数据库里的密码属性都是int型 ,不曾设置成String型,别说登录上去,就连插入数据库都插不进去。谈何登录注册呢?这倒是引起了我的思考,于是我就在百度上查查相关资料吧,这才知道所有通过页面传递到参数都要设置成String类型的,那我的系统能侥幸存活下来不过是因为我的id和密码设置成int型后,对从页面获取到的string数据都进行转换,就产生了在整个后天程序中出现的参数都是int类型,在于数据库进行交互的时候的不会出错!但是正是这个操作也大大的加大了我的系统的局限性——只能使用数字作为密码!这样也正验证了为什么当初想当然写的
int id = request.getParameter(“id”); 会报错,然而String类型的确实安然无事,原来系统早就默认了在页面的参数为String类型。这样的话要想改进这个系统就需要对数据库的表进行修改了,索性就把所有属于int的改为char,这样一来既可以增加密码的扩展性还可以简化了代码。这里对我来说是一个很大的教训,也是一次很大的一次教训!
另外,在观赏其他同学的作品的时候我发现其实也有好多的优秀的作品特别的让人眼前一亮。尤其是B/S端的几个特别优秀的,可以看到他们在上面下足了功夫,整个界面的美化没得说,色彩运用的中规中矩,甚至让我有点怀疑所看到的是不是一个大三做出来的还是正在上网,除此之外,他的功能实现也很丰富,可以从页面一侧拉出来功能菜单,并且功能项特别俱全。还有一个是类似于网购的应用,其界面的功能的强大和美工专业性让我叹为观止啊!当时我发自内心的感慨何异于淘宝京东呐!在同学们演示的C/S作品中,也看到了很多优秀的作品,个人认为他们的界面美化相对稍逊色与我们的B/S端,但是那么几个人的做的功能实在强大的很,就拿直观的说吧!那么多的按钮,每一个按钮都要实现功能吧,不然设置他做什么呢?然而,我觉得他们了不起的地方在于,那么多的调用和实现,感觉有好多的界面需要来跳来跳去,给人一种“哇!这个的确是一个系统!”的感觉!这种类型的作品就是典型的乍一看看不出啥新鲜的,但是你越看越觉得的他的精彩!突然发现软件班都是藏龙卧虎的地方!反观自己的这个作品,着实相对单薄了许多,用户界面较为单一,缺少特别亮眼的地方,实现了基本的增删改查外加简单的美工,相形见绌说的就是如此吧!但是,我毕竟是付出了时间和精力的,相对于大多数同学的作品来说,我还是有信心说我的作品不是优秀也是良好。
这是我的第一个小项目,我尽我所能把他做好,把他做成成熟大人的样子,尽管他的本质还是个孩子,但是他刚刚学会走路却从他的身上看出了要茁壮成长的雄心壮志。从这个项目中也使我深深体会到了程序员的不容易,曾经我对程序员的看法就是作者,写文章的作者,只要把自己的想法清清楚楚的表达出来,再加上一点点的润饰,那么一篇优秀的作品就会成功出世!至此之后,我感觉自己有点那么的无知,学了这么多年的计算机了,才这些觉悟实在是惭愧啊!作为一名程序员,最首先要有的不是丰富的知识,不是什么牛X的技巧而是要有强大的抗打击能力,百折不挠的精神!我是这样想的,即便是在深厚的知识积累,在牛的技巧,在开发的过程中难免会出现bug满天飞的情况,如果一名心态脆弱的程序员心思缜密的做完一段程序,立志要一次性成功,结果百密一疏出现了一个bug也可能导致出现一大堆错误,那么岂不是立马心态崩了。以上举例仅为说明开发者的心态的重要性,千万要戒骄戒躁,沉下心来,相信世上无难事,只怕有心人!这是我被这个系统折磨这么多次体会到的真谛。其次,在讲知识和技巧的积累和运用,坦白讲,之前讲的心态最重要只不过为了说明他的重要性,知识和技巧才是开发的前提,没有知识和技巧谈开发不过是纸上谈兵,就连心态炸裂的机会都没有!回到正题,我经此一役感受到的就是技术的灵活运用的重要性,为了实现的相同的功能,采用什么技术什么方法才会更高效,更快捷,更加的稳定,这其实都是非常值得考虑。就比如说的小一点,同样的从1加到100,不会编程的人会拿计算器算,会编程的人会使用循环算,编程好的人会使用高斯算法,不会编程的人抛开不谈,使用高斯算法的人会更快更省力的解决这个问题。这就是一个简单的算法的优化的问题,但是我引申为选择更加适合的高效的技术来完成目前的所接到的项目。在这次的开发中,我很庆幸我选用了jsp作为我的主要开发手段,它和java的高度兼容性使我不论在后台或者前台都不会受制于语言的弊端。惭愧的说更多的是自己的编程水平拖后腿了,没有运用好啊。他给我带来的前端后台可以左右开工,不仅有高效的后台做支撑,前端的展现也是毫不逊色,这就是我想提到的选用优秀的知识体系和技巧的重要性。
以上就是我在这次开发所做出的总结和心得,其中有很多的故事,有为想不出解决办法不愿意和室友说话的愤懑,有半夜想不出办法无法入睡的失眠的痛苦,有要不要坚持下去的纠结,有做梦出bug的惊醒,更有成功解决问题时天下唯我独尊的畅快淋漓!