@ModelAttribute标记在方法上, 当执行控制器中任何一个方法时,都会先执行@ModelAttribute标记的方法,因此若一个执行控制器中有多个方法时,谨慎使用@ModelAttribute,避免效率问题。
应用场景:避免前端未传参,导致数据更新为null,适合方法比较少的控制器。
用法1:@ModelAttribute有返回值
执行控制器的方法时,会检查执行方法中 参数的属性是否为null,如果为null,则使用标记@ModelAttribute的方法的返回值 覆盖null的数据。
index.jsp
<form action="${pageContext.request.contextPath}/user/testUpdate" method="post">
<input type="hidden" name="id" value="1">
<input type="text" name="username">
<!--此处不提交sex-->
<%--<input type="text" name="sex">--%>
<input type="submit" value="提交">
</form>
User.java
public class User {
private Integer id;
private String username;
private String sex;
//省略getter setter toString
}
UserController.java
@RequestMapping("/user") //请求路径
@Controller
public class UserController {
/模拟根据id查询一个用户
@ModelAttribute
public User findById(Integer id){
User user = new User();
user.setUsername("王五");
user.setSex("女");
return user;
}
/*模拟 update user set username = ?, sex = ? where id = ?
@ModelAttribute:在执行控制器中任何一个方法时,都会先执行
findById方法返回一个User对象
判断参数user中的属性是否为null,如果为null,则使用findById的方法返回值中的数据覆盖
*/
@RequestMapping(value = "/testUpdate", method = RequestMethod.POST) //请求路径
public String testUpdate(@ModelAttribute("user") User user){
System.out.println(user);
System.out.println("更新");
return "show";
}
}
输入姓名点击提交,后台打印结果,表单提交时,sex为null,执行testUpdate,发现sex字段已经被@ModelAttribute覆盖为“女”。
如果这里没有@ModelAttribute,那么sex为null,若这里有更新操作,那么数据库中的sex就会被更新为null。很明显,这样更新是有问题的。
用法2:@ModelAttribute没有返回值,可以使用map
只修改@ModelAttribute标记的方法,和使用数据的方法的形参
//@ModelAttribute标记的方法没有返回值
@ModelAttribute
public void findById(Integer id, Map<String ,Object> map){
User user = new User();
user.setUsername("王五");
user.setSex("女");
map.put("aa",user);//使用map
}
@RequestMapping(value = "/testUpdate",method = RequestMethod.POST)
public String testUpdate(@ModelAttribute("aa") User user){//找@ModelAttribute标记的方法中map内的"aa"
System.out.println(user);
System.out.println("更新");
return "show";
}
执行效果与用法1一致