springMVC小总结
常用注解总结
以下内容是我个人对@ModelAttribute注解的见解,如有错误请批评指正!!!
例子中用到的代码:代码获取
@ModelAttribute注解
1.作用:
- 出现在方法上:表示当前方法会在控制器方法执行前先执行
- 出现在参数上:获取指定的数据给参数赋值
2.应用场景:
-
当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。
这句话的理解:比如说数据库中有一个user表,表中有三个字段(name,age,birthday),并且有一条 name=张三,age=18,birthday=20201229的数据; “当提交表单数据不是完整的实体数据时”:前端表单中只有name和age字段 “保证没有提交的字段使用数据库原来的数据”:要保留birthday字段 说白了就是要只更新这条数据的name和age字段!!!保留原来的birthday
3.小栗子:
需求:
现在我的数据库中有一条 id=2,name='张三',age=20,password=123456的数据;
现在我要做的就是通过前端的form表单来更新这条数据的name和age字段;
不使用@ModelAttribute注解产生的问题:
前端:
<form action="testModelAttribute" method="Post">
<input type="hidden" name="id" th:value="${user.id}"/>
name:<input type="text" name="name" th:value="${user.name}"/><br>
age:<input type="text" name="age" th:value="${user.age}"/><br>
<input type="submit" value="提交"/>
</form>
控制器:
@RequestMapping(value = "/testModelAttribute",method = RequestMethod.POST)
public String testModelAttribute(User user){
usersService.updateUser(user);
System.out.println("【后执行】修改后"+ user);
return "success";
}
执行结果:
前端页面输入:
控制台打印:
【后执行】修改后User{id=2, name='李四', age=54, password='null'}
分析:这样做的话会把原数据的password字段变为null
使用@ModelAttribute注解解决此问题:
用法一:使用@ModelAttribute修饰返回值是一个po对象的方法
假设数据库还是id=2,name=‘张三’,age=20,password=123456这条数据;
控制器:
//被@ModelAttribute修饰的方法会先执行
@ModelAttribute
public User getUser(Integer id){//获取隐藏域中的id
//通过id把对应的数据先查出来
User user = usersService.findUserById(id);
System.out.println("【先执行】根据id从数据库中查出的user"+user);
return user;
}
@RequestMapping(value = "/testModelAttribute",method = RequestMethod.POST)
public String testModelAttribute(User user){
//修改数据
usersService.updateUser(user);
System.out.println("【后执行】修改后"+ user);
return "success";
}
执行结果:
前端页面输入:
控制台打印:
【先执行】根据id从数据库中查出的userUser{id=2, name='张三', age=20, password='123456'}
【后执行】修改后User{id=2, name='哈哈哈', age=28, password='123456'}
用法二:使用@ModelAttribute修饰返回值是空的方法(此时@ModelAttribute可以放在方法的参数上来给方法赋值)
假设数据库还是id=2,name=‘张三’,age=20,password=123456这条数据;
控制器:
@ModelAttribute
public void getUser(Integer id, Map map){
User user = usersService.findUserById(id);
System.out.println("【先执行】根据id从数据库中查出的user"+user);
map.put("abc",user);
}
@RequestMapping(value = "/testModelAttribute",method = RequestMethod.POST)
public String testModelAttribute(@ModelAttribute("abc") User user){
usersService.updateUser(user);
System.out.println("【后执行】修改后"+ user);
return "success";
}
执行结果:
前端页面输入:
控制台打印:
【先执行】根据id从数据库中查出的userUser{id=2, name='张三', age=20, password='123456'}
【后执行】修改后User{id=2, name='哼哼哼', age=16, password='123456'}
到这里的疑惑:
明明getUser方法中往map里放的user是id=2, name=‘张三’, age=20, password=‘123456’
为什么在 testModelAttribute(@ModelAttribute(“abc”) User user) 中的user会是User{id=2, name=‘哼哼哼’, age=16, password=‘123456’}呢?
以下是我的猜想:
这是因为@ModelAttribute注解会获取到form表单中的数据:id=2,name=“哼哼哼”,age=16,password="";
然后将从数据库中查到的数据:id=2, name=‘张三’, age=20, password=‘123456’ 做了一个“整合”,得到最终
数据:id=2,name=“哼哼哼”,age=16,password=“123456”;