Spring MVC 3.0:如何绑定到持久对象

时间:2010-09-08 21:37:18

标签: spring data-binding spring-mvc persistence spring-3

我正在使用Spring MVC,我希望它能从数据库中绑定一个持久对象,但是我无法弄清楚如何设置我的代码以在绑定之前调用DB。例如,我正在尝试将“BenefitType”对象更新到数据库,但是,我希望它从数据库中获取对象,而不是创建新对象,因此我不必更新所有字段。

    @RequestMapping("/save")
public String save(@ModelAttribute("item") BenefitType benefitType, BindingResult result)
{
    ...check for errors
    ...save, etc.
}

4 个答案:

答案 0 :(得分:4)

有几种选择:

  • 在最简单的情况下,当您的对象只有简单属性时,您可以将其所有属性绑定到表单字段(如果需要,hidden),并在提交后获取完全绑定的对象。复杂属性也可以使用PropertyEditor s绑定到表单字段。

  • 您还可以使用会话在GETPOST请求之间存储您的对象。 Spring 3通过@SessionAttributes注释(来自Petclinic sample)来推广这种方法:

    @Controller
    @RequestMapping("/owners/*/pets/{petId}/edit")
    @SessionAttributes("pet") // Specify attributes to be stored in the session       
    public class EditPetForm {    
        ...
        @InitBinder
        public void setAllowedFields(WebDataBinder dataBinder) {
            // Disallow binding of sensitive fields - user can't override 
            // values from the session
            dataBinder.setDisallowedFields("id");
        }
        @RequestMapping(method = RequestMethod.GET)
        public String setupForm(@PathVariable("petId") int petId, Model model) {
            Pet pet = this.clinic.loadPet(petId);
            model.addAttribute("pet", pet); // Put attribute into session
            return "pets/form";
        }
        @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST })
        public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
            new PetValidator().validate(pet, result);
            if (result.hasErrors()) {
                return "pets/form";
            } else {
                this.clinic.storePet(pet);
                // Clean the session attribute after successful submit
                status.setComplete();
                return "redirect:/owners/" + pet.getOwner().getId();
            }
        }
    }
    

    但是,如果在同一会话中同时打开表单的多个实例,则此方法可能会导致问题。

  • 因此,对于复杂案例,最可靠的方法是创建一个单独的对象来存储表单字段,并手动将该对象的更改合并到持久对象中。

答案 1 :(得分:4)

所以我最后通过在类中使用同名的@ModelAttribute注释一个方法来解决这个问题。 Spring在执行请求映射之前首先构建模型:

@ModelAttribute("item")
BenefitType getBenefitType(@RequestParam("id") String id) {
    // return benefit type
}

答案 2 :(得分:0)

虽然您的域模型可能非常简单,您可以将UI对象直接绑定到数据模型对象,但更可能的情况并非如此,在这种情况下,我强烈建议您专门为表单设计一个类绑定,然后在它与控制器中的域对象之间进行转换。

答案 3 :(得分:0)

我有点困惑。我想你实际上在谈论更新工作流程?

你需要两个@RequestMappings,一个用于GET,一个用于POST:

@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getSave(ModelMap model, @PathVariable Long id)
{
    model.putAttribute("item", benefitDao.findById(id));
    return "view";
}

然后在POST上实际更新字段。

在上面的示例中,您的@ModelAttribute应该已经使用类似上述方法的方法填充,并且使用JSTL或Spring tabglibs以及表单支持对象绑定属性。

您可能还希望根据您的使用情况查看InitBinder