package com.atguigu.controller;
import com.atguigu.controller.com.atguigu.bean.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 很多业务只要对部分字段进行修改,以修改图书信息为例
* bookName通常是不能修改的
* (1)不修改的字段可以在页面展示,但是不能修改
* (2)为了简单,controller直接在参数位置来学Book对象
* (3)SpringMVC为我们自动封装book(没有带的值是null)
* (4)如果接下来调用了全字段更新的dao操作,那么前端可能没有带过来可显示不可修改的值,这个字段后端默认它的的值为null。
* sql = "update book set"
* if(book.getBookName()!=null){
* sql+="bookName=?,"
* }
* if(book.getPrice()!=null){
* sql+="price=?"
* }
* (5)如何保证全字段更新的时候,只更新了页面携带的数据
* ①修改dao,代价太大
* ②Book对象是如何封装的?
* 1、springMVC创建一个book对象
* 1、解决思路:让springMVC别创建book对象,直接从数据库中先取出ID=1的book对象的信息
* Book{id=1, bookName='西游记', author='123', stock=23, sales=123, price=1231.0}
* 2、将请求中与所有book对象对应的属性一一设置过来,bookName默认就是null
* 2、解决思路:使用刚才从数据库取出的book对象,给它里面设置值(请求参数带了哪些就覆盖之前的值)
* 3、前端未带值过来,那么bookName就一直是null,调用全字段更新导致数据库中bookName修改为null
* 3、解决思路:带了的字段就改为携带的值,没带的字段就保持之前的值。
*/
@Controller
public class ModelAttributeController {
private Object o1;
private Object o2;
/**
* @ModelAttribute("book"): 取出保存在ModelMap中的key为“book”的数据
* 告诉SpringMVC不用new Book了,用testModelAttribute读取的Book对象。
*/
/*
@RequestMapping("/updateBook")
public String updateBook(@ModelAttribute("book") Book book){
System.out.println("页面要提交过来的图书信息"+book);
//bookDao.update(book);
return "success";
}
*/
/**
*使用ModelMap获取book参数
*/
@RequestMapping("/updateBook")
public String updateBook02(ModelMap modelMap) {
//将modelMap赋值给o2
o2 = modelMap;
//true,也就是说updateBook02中的modelMap与testModelAttribute中的modelMap是一个同对象
System.out.println("o1==o2?" + (o1 == o2));
//直接从modelMap中取出book对象,与
Book book = (Book) modelMap.get("book");
System.out.println("页面要提交过来的图书信息" + book);
return "success";
}
/**
* (1)SpringMVC要封装请求参数的Book对象不应该是自己new出来的,而应该是数据库中拿到的准备好的对象。
* (2)再来使用这个对象封装请求参数
*
* @ModelAttribute: 参数:取出保存在ModelMap中的数据
* 方法:这个方法就会提前于目标方法先运行
* ①这里提前查出数据库中图书的信息
* ②将这个图书信息保存起来(方便下一个方法还能使用)
*/
@ModelAttribute
public void testModelAttribute(ModelMap modelMap) {
//因为modelAttribute会提前运行,所以在此方法中模拟从库中查出book对象
Book book = new Book();
book.setId(1);
book.setBookName("西游记");
book.setAuthor("吴承恩");
book.setPrice(12.3);
book.setStock(100);
System.out.println("数据库中查到的图书信息是:" + book);
modelMap.put("book", book);
System.out.println("查询了图书并保存起来了。");
//将model赋值为o1
o1 = modelMap;
System.out.println("modelAttribute方法...");
}
}
原理图解: