本文继续上一篇文章中的内容,在ssm框架中实现批量删除与修改的功能。批量删除的逻辑就是将需要被删除的商品id,封装成一个集合传入到controller中,然后对集合进行遍历,每一次遍历时执行delete from table where id = ?语句。那么如何将多个id同时传到controller呢?
完成多个id的发送需要一个checkbox,被用户勾选的checkbox中的 id就会被传进controller,下面我们看jsp页面。
在forEach下的td标签中添加checkbox类型的input标签,下面进入controller。
这里使用Integer[] 数组来接收参数,然后将ids传入service中的batch方法。
在service方法中,我们只需要对数组进行遍历,每次遍历时执行一次删除方法即可。那么我们能否完成对商品的批量修改呢,此处只修改商品的名称这种属性。这时候我们需要将每一条被用户勾选checkbox的商品id,以及商品属性作为参数传入controller,那么这时候就不可以使用Integer[]来接收参数了,我们需要使用List集合来接收参数,那么jsp页面发送参数时,要怎样写才可以将参数封装到List中呢。下面看jsp页面
我在进行测试的时候遇到了一个小bug,controller接收到的参数 id 有值,price有,name死活就没有值,数据库一直报错,debug看了好几次,一直想不出什么原因,requestHeader也看了,字符串一点毛病都没有。费了好长时间才可以见,input里面的name属性居然有个空格,springmvc也真是够奇葩的,它居然把空格给读了,突然不喜欢这个框架了。下面我们看修正之后的jsp页面代码
springmvc是不能接收List类型的参数的,所以我们必须把list封装到一个对象QueryVO中去。那么前台传过来的参数名必须是list[0].name,list[1].name这种形式,所以就不能把input的name属性写死。这里使用了forEach标签中的varStatus属性,下面有varStatus用法
我们需要使用index,因为list集合的索引是从0开始的,通过EL表达式动态获取它的index就能和List中的索引对应起来了,下面我们看controller代码
这里把包装类直接交给service处理了,所以我们进入到service
批量更新的原理也很简单,与批量删除一样,在forEach中执行更新语句,这也就是业内的一个专业名词,跑批。下面说一下requestMapping的用法,
有的项目可能会要求,为items单独创建一段url然后在后面跟方法名,@RequestMapping写在类的头上的作用就是,该类下的所有方法的实际url=类头requestMapping+方法头requestMapping,会对他们进行一个拼接。这个注解有六个属性,除了key为value能表示url外,当key为method时,会限定请求类型,比如说post,get请求啊等等。可以这样写method={post,get}以这种形式组合多个参数,那value也可以有多个参数进行组合,多个url可以访问同一个controller方法。还有一个参数是consumes,用于指定请求体格式Content-Type,例如application/json, text/html;如果前台使用ajax发json,springmvc这个愚蠢的框架就解析不出来,必须在requestMapping中告诉它。produces和consumes一样,用于指定response中的Content-Type格式。还有两个参数params和headers,要求请求体中必须包含params或headers才可以访问该方法,可能用于加密。
看一下这个controller,这种写法可以直接返回View的name,在形参中传入model,然后将数据添加到model中,这种方法能减少代码量,却有抄袭Struts2的嫌疑。下面我们看一下model的源码
实现类中居然是个concurrentModel,前面带有concurrent的均为同步容器,意思就是说能够保证并发安全。
进去一看发现它偷了个懒,直接给jdk提供的concurrentHashMap直接拿来用了,如果我们以后写框架的话也可以这样做,Java的三大特性中的继承有时候会用的很巧妙的。
图中的写法是进行重定向的操作,只要返回redirect:加上View的name就能完成重定向了,那么在前后端分离的开发中,需要返回json数据时该怎么写呢
直接将返回值设为void,此时不发生重定向也不会进行页面跳转了。springmvc的最大特点就是代码量少。大家学会了吗,请在下方留言吧,如果有不明白的地方在评论区留下问题我会回复的。