1,使用场景
修改数据库记录,但是有些字段不能被修改(以对象的方式进行更新)
传统解决方法:
1.表单中加一个隐藏域,用于存储不能被修改的值
缺点:对于敏感信息(密码)不适合和对于不能修改的字段值比较多的话不适合
2.先创建一个对象,查询数据库为对象赋值,再把表单传来的值进行更新
缺点:太低效
@ModelAttribute的解决方法:
在从表单取得字段值之前,先从数据库中取得该对象(已赋值),此对象相比传统的解决方法第二点,对象不是新创建出来的,而是从数据库中取得的,再把表单的值进行更新
2.示例代码
@ModelAttribute public void getUser(@RequestParam(value = "id",required = false) Integer id,Map<String,Object> map){ if(id!=null){ //模拟从数据库中获取对象 User user=new User(1,"Tom","123456"); System.out.println("从数据库中获取一个对象:"+user); map.put("user",user); } } @RequestMapping(value = "/testModelAttribute",method = RequestMethod.POST) public String testModelAttribute(User user){ System.out.println("修改:"+user); return "study_success"; }
注意:
1.有@ModelAttribute标记的方法,会在每个目标方法方法执行之前被调用(类比过滤器)
2.在@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型(User)的第一个字母小写的字符串一致(user)
也可以用@ModelAttribute注解修饰目标参数,指定名称
public String testModelAttribute(@ModelAttribute("user")User user){}
3.若在@ModelAttribute注解的方法中的map中,没有找到相应的键,则检查当前是否使用@SessionAttributes注解修饰,若使用了该注解,且其包含了相应的键,则会从httpSession中获取相应的对象,
若该对象存在,则直接传入目标方法的入参,否则抛出异常
若也没有使用@SessionAttributes注解或其不包含相应的键,则会通过反射创建对象,传入为目标方法的入参
3.运行原理
大致运行流程:
1.执行@ModelAttribute注解修饰的方法:从数据库中取出对象,把对象放到了Map中,键为:user
2.SpringMVC从Map中取出User对象,并把表单的请求参数赋给该User对象的对应属性
3.SpringMVC把上述对象传入目标方法的参数