SpringMvc+Mybatis实现一个简单人事管理系统(二)

    本篇文章主要说的是项目的搭建

        我学springmvc是看着疯狂java系列的《spirngmvc+mybatis企业应用实战》,书中最后一章是搭建一个系统,内容很多,我花了两天时间,把代码敲了,还把书中的注释也打上了,方便日后整理。在敲的过程中,我学到了很多,比如代码的规范,以及做为一个项目应该有的目录结构.

  让我体会比较深刻的是,接口的规范。当我敲service层时,我不是很理解为什么要写一个接口,然后再来继承他,写接口的实现。之前书上说的,加上我之前学的,也都只是说这样可以实现一种标准,一种规范。觉得这些都是大家都知道的规范,没必要那么麻烦。可当我在敲这个代码时,我发现,接口不仅仅是提供一种规范,因为在接口方法名写上了注释,当需要了解或者调用方法时,直接看注释并调用即可,非常方便。之前我也有想过,直接在一个类中(没有继承接口)写这些方法,并加上注释或者方法说明,也能达到一样的目的,但是如果这些方法有很多个呢,我写的这个项目service接口就有36个接口,如果放在一个类中挨个写,再加上注释,这个文件将会大大降低可读性,而放在一个接口中,可以一目了然,也方便自己和他人了解函数方法和以后的维护。

  在敲完一遍代码后,我满心欢喜的去运行,果不其然,各种报错。有些错误,是语法错误,在idea中就会提示,你只需根据提示进行修改即可,而有些错误,是逻辑错误,经常就是点击一个链接或者敲入url后,报404或者500错误,在这之前,我比较喜欢的做法是,觉得有问题的代码把他先注释掉,或者在其中加入log日志打印,看看到底哪里出问题,从而进行修改。我也知道调试,但我觉得,加注释或者日志方法更“简单粗暴”,可这种方法解决一些逻辑相对比较简单,代码量相对比较的小的demo还行,但遇到一些比较大的项目,这种方法很难有效解决问题。还好之前,主管教会了我具体怎么调试,于是我慢慢调试,并根绝里面信息进行修改代码。终于能够成功运行,当时感觉就是成就感爆棚,虽然这只是敲出来的,而不是自己写的。人事系统大致如下:

 这是登录页面

SpringMvc+Mybatis实现一个简单人事管理系统(二)_第1张图片

这是登陆成功后的主页

SpringMvc+Mybatis实现一个简单人事管理系统(二)_第2张图片

        因为我之前没写过什么项目,所以对于安全性这一块我基本没什么概念,当我把我写的demo给主管看的时候,我甚至还说“拦截器”没什么用这样的话,因为我在敲拦截器代码的时候,发现这段代码只是拦截一些网址,我心想,如果网址不对,那肯定就不能访问这个项目呗,为什么还要进行拦截呢,感觉有些多余,于是就把拦截器代码给暂时注释了。主管马上就用了我项目中一个表格的url地址进行输入,发现可以直接访问,并且是在我没有登录的情况下!所以在那之后,我重新思考了拦截器的作用,才发现拦截器是一个springmvc中很重要的部分,我项目中用到的拦截器功能是拦截网址,正常情况下,在未登录时,应该访问首页,此时若输入其他不相关url或项目中一些信息表格的url时,拦截器将会拦截,跳转到首页并提示相关信息。而用户登录后,此时若输入项目表格信息时,将会正常显示,因为已经登录,拥有访问这些数据的权限。于是我重新调整拦截器代码,发现一个问题,我用代码来说明比较清楚,我的首页地址是http://localhost:8023/hrm/loginForm,按照书本上的代码以及日常逻辑来说,如果我把首页url去掉一个m此时输入http://localhost:8023/hrm/loginFor,那么拦截器将起作用,自动调转到首页,然而,当我输入项目数据url时,比如http://localhost:8023/hrm/notice/updateNotice?flag=1&id=1虽然也能跳转到首页,但首页一些样式已经变了(因为用了ligerui样式,导致路径不对),样式不对,还可以改,最重要的是,登录不了了,因为此时,url已经变成了http://localhost:8023/hrm/notice/login,正常来说只有url为http://localhost:8023/hrm/login才是正确登录验证路径,我一开始不懂里面原因,认为是转发与重定向问题,书本上的例子是说用request.getRequestDispatcher方法,通过转发,把页面跳转到loginForm,同时获取request请求里的attribute属性,显示到jsp页面中。我认为转发只是把当前url后再加上/loginForm,当url后有个多个“/”时,将出现问题,所以我采用重定向方法,用response.sendRedirect方法直接重定向到http://localhost:8023/hrm/loginForm,然而这样会失去request里面的数据,因为重定向前后两个request并不一样,我上网搜了好多解决方案,都不能有效解决问题,但有篇博客提到了拦截器接口的三个方法,让我重新调整了思路,我在想能不能直接用session的attribute属性来代替request,因为拦截器的pre方法是在controller处理前调用,在这个方法里我直接给session加上属性,使得在jsp页面直接调用sessionscope里的属性值,而在after方法里,我把session属性值移除了,这样就可以大概把session变成了request。而且在调试过程中也一切正常。后来,主管帮我分析了一下转发方法为什么不行,原来是在form表单中的action属性里忘了添加/,我在前一篇中已经分析了url中加/和不加/的区别。通过这几个问题,我算是深刻意识到了url中的/的重要性了!

  之后的我陆陆续续修改了mysql的权限,自定义了一个只具有增删查改权限的用户,代替root权限,保证数据库的安全,以及其他的一些页面bug,比如无法正常注销,点击首页标签没有反应,取消按钮出错等。在这之后,我又想着给这个系统一个更加完善的功能————数据验证。数据验证的大致效果如下图:SpringMvc+Mybatis实现一个简单人事管理系统(二)_第3张图片

      上图中的按钮是我后来自己添加的。  

  我一开始以为Mybatis框架应该有比较完善的数据验证方法,我搜了一下,发现有个JSR303验证,可里面的方法只能进行验证是否为空或者是否符合既定标准,无法连接数据库进行数据是否存在验证,而且必须得提交表单后才能进行验证,不是很好用。所以我用JQuery的ajax验证,我在课余时间有学过JQuery,也有敲过ajax的相关代码,但现在早就忘了。在简单搜了ajax方法demo后,我就在jsp中写了下,大致如下:

   function  checkusername() {
            var username=$("#username").val();
            $.ajax({
                type:"POST",
                url:"${ctx}/user/checkusername",
                data:{
                    username:username
                },
                dataType:"json",
                success:function (_data) {
                    if(_data.status=="0"){
			$("#user_div_1").html("

"+_data.msg+"

"); $("#username").focus(); }else{ $("#user_div_1").html("

"+_data.msg+"

"); setTimeout(function () { $("#user_div_1").html("

"); },1000); } } }) }
   写完了这些,我开始在dao组件中添加相关数据库验证方法,大致如下:

       @Select("select * from "+USERTABLE+" where binary username = #{username} ")

              User selectByUsername(String username);

      在controller层中,我添加了相应的逻辑实现方法,具体如下:

	@RequestMapping("/user/checkusername")
	@ResponseBody
	public Result checkUsername( String username){
		User user=userDao.selectByUsername(username);
		if(user==null) {
			return new Result("1","恭喜!用户名可用");
		}
		else{
			return new Result("0","抱歉!用户名已存在");
		}
	}
  对于这段代码,我本来都不知道应该如何传递验证结果的,后来在同事帮助下,我知道了vo层,虽然也是pojo,但主要应用于展示层的pojo,虽然和do一样,都只有属性以及get/set方法。

  通过这几段代码,我觉得springmvc对各个组件分工明确,大大降低了代码之间的耦合度,从而让项目更有利于管理,我的理解是,更容易找出bug在哪个组件中。接下来的事情是在jsp页面中,如何展示出来,这个过程应该是最麻烦的事了。虽然数据验证都对,但是展示出的页面的用户体验特别不好,比如,为每个输入框设置“blur”事件,即每次输入完后,马上进行验证,如果正确,光标将聚焦到下一行,如果不正确,光标自动聚焦到当前行,并提示相应信息。虽然逻辑看起来简单,其实实现起来很麻烦.最开始,我给四个输入框都加入了blur属性,然而,我一旦输入完某一个属性后,光标移到下一行,该行已经自动提示错误信息——不能为空,于是我采用change事件来代替blur事件,发现效果并不好,还是只能用blur事件,仔细看代码才发现,我在某个错误信息后少加了个this.focus方法,才导致了不良体验。

  之后我把ajax方法加到检查按钮中的click事件中,但又有了个问题(事后证明,我这个想法有点极端),如果用户在输入完信息后,不马上点击检查是否注册按钮,而直接输入下一行呢,于是又加了个变量username_click,判断是否点击过注册按钮,如果没有,则提示先点击注册按钮,此时,我又开始纠结,此时光标聚焦在文本框上还是直接聚焦在按钮上,我最后两种方法都试了,还是觉得放在文本框上好一些,哈哈,有点强迫症。业务功能的实现有一点我很喜欢,就是你实现了一个功能并验证无误后,马上可以复制粘贴代码,快速为其他文本框添加该功能,每当这样做的时候,感觉超棒!全部验证完后,我突发奇想,如果有用户在验证成功后,并输入完所有表格信息后,在准备提交表格时,他又修改了之前验证通过的用户名并且恰好改成了已经存在的用户名,这种行为肯定是不行的,于是我终于使用上了change事件,为每个需要进行数据库验证的文本框加上change事件,但内容有变化时提示,单机按钮进行验证。

  看上去万事大吉,好像一切都很正常,然而,当我要提交表单时,我才发现,哪怕了错误,我依然可以提交表单,并且顺利提交到数据库中!我看了submit函数,发现里面只进行了是否为空判断,并未进行其他错误信息的判断,于是我又在js代码块中加了4个全局变量,分别对应4个输入框的错误信息,在submit函数中,把这4个变量赋给局部变量msg,从而进行判断,能否通过验证。这样就顺利解决了问题,在进一步的调试中,我发现,只要判断最后一个文本框的是否有错误信息即可,因为我的代码逻辑是,只有前一行正确无误后,才能输入下一行,否则下一行无法输入,此时若想提交表单,将弹出错误框,无法提交。

  这一切看上去又都很正常,然而,当我测试页面其他按钮时,果然不其然的又不行了,当我想要点击清空按钮时,一直无法生效,反而出现错误信息——内容不能为空。应该是blur事件的原因,于是我上网搜了js所有的事件,看看有没有的好解决办法。我看到事件中有mouseover和mouseout,心想能不能给清空按钮添加这两个事件,在mouseover事件中把所有blur事件都移除,而mouseout事件使得这些blur事件重新加上。即当我鼠标移动到按钮时,blur事件消失,使得我能够顺利点击清空按钮并生效,而清空完,当我将光标重新移动到输入框时,blur事件又重新添加,从而又能够进行数据验证。果然将我的逻辑转换为代码时,终于成功了,但是,新的问题也出来了,清空按钮并未将错误信息也清空,于是我给错误信息标签设置了class,在清空按钮中添加这些class的清除事件,终于大功告成!接下来的事情,就是给其他模块也添加上数据验证功能。再给其他模块添加功能时,我发现,完全可以不用有mouseout事件,可以直接将mouseout事件中的逻辑代码移到click事件中,即点击清空按钮,自动添加输入框的blur事件,具体代码如下

SpringMvc+Mybatis实现一个简单人事管理系统(二)_第4张图片


      这一切看上去还是很正常,然而,还是出现了问题,在给employee添加功能验证时,数据验证功能无法实现,我一开始以为是我复制时候哪里少复制了,或者有些该改的地方没改成employee,可等我仔细检查了一遍,发现一切都没问题,可验证功能老是不行,我用网页调试器看了ajax请求,发现是这里出了错,因为request的请求内容是文本框的输入内容,而response却一直不对,我以为是jsp页面ajax没写好,为此还特意仔细看了ajax的使用说明,发现自己写的没问题,于是,我又用idea进行调试,我看到代码跳转了一个InvocationTargetException函数中去,很是奇怪,我百度了这个异常,发现这个异常是由当被调用的方法的内部跑出了异常而没有被捕获时,将由此异常接收。还好,强大的idea给我指出了具体出处:

      原来是我的sql语句出了错,这是我怎么都没想到的,因为这语句简单的不能再简单吧。我的sql语句如下:

      因为在之前我写的sql语句中,where后面基本上都是xxx=#{xxx},所以这次我也想当然的以为,cardId=#{cardId},一查数据库才发现,我的字段名为card_id,在我改了之后,验证功能顺利实现。

  至此,数据验证功能全部实现,当我验证employee验证按钮时成功时,我感到了一种前所未有的开心,因为这个功能是我自己写的,而并非照本宣科的参考书本(书本上案例也没有这功能)。同时,我也明白了两个道理,一个是复制粘贴时,不能一昧简单无脑的修改,还要结合其他条件,比如数据库对应的字段名等,还有就是mybatis框架虽然提供了让开发者自己写sql这样自由的空间,但前提是你不能写错。不过还好,强大的idea能够发现sql语句的逻辑错误,这大大提高了开发者的效率。也因为如此,让我第一次感受到idea的强大。

       

  总结:总体来说,写人事管理系统,就好像建房子一样。第一部分是初期的代码构造部分,就好像建房时的打地基,用砖头把房子搭起来,使得人事管理系统有了大致的样子,就像毛坯房一样,但还有很多细节没有实现。第二部分是补缺补漏,修复系统一些bug问题,完善基本功能,就好像新房子装修一样,变得干净整洁。第三部分是实现高级功能,作为一个简单的人事管理系统,最重要的是数据的输入输出,所以数据验证问题变得十分重要,通过实现这些功能,人事管理系统也就变得更加完善了,用户体验也提高了,就好像新房子添加了家具,从干净整洁变得精致舒适,可以住人了。

你可能感兴趣的:(SpringMvc+Mybatis实现一个简单人事管理系统(二))