ModelAttribute注解的使用

本文详细解析了SpringMVC中@ModelAttribute的使用,讲解了如何处理部分字段更新的问题,避免数据库中重要字段因为空值被更新。通过案例展示了如何从数据库获取预填充的对象,然后覆盖前端传递的参数,确保只更新实际修改的字段,同时避免了全字段更新带来的潜在问题。此外,还探讨了解决方案,包括利用ModelMap和@ModelAttribute注解的方法。
摘要由CSDN通过智能技术生成
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方法...");
    }

}

原理图解:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值