我是Spring的新手,我正在尝试创建一个RESTful资源以在我的API上使用。到目前为止,我能够列出元素(GET /people.json),显示特定元素(GET /people/{id}.json),创建新元素(POST /people.json),并删除元素(删除/people/{id}.json)。我的最后一步是处理更新方法(PUT /people/{id}.json,但我不知道该怎么做。
以下是我的控制器代码:
package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.model.Person;
import com.example.service.PersonService;
import java.util.Map;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@ResponseBody
@RequestMapping(value = "/people.json", method = RequestMethod.GET)
public String all(Map<String, Object> map) {
return "{\"people\": " + personService.all() + "}";
}
@ResponseBody
@RequestMapping(value = "/people/{personId}.json", method = RequestMethod.GET)
public String show(@PathVariable("personId") Integer personId) {
Person person = personService.find(personId);
return "{\"person\": "+person+"}";
}
@ResponseBody
@RequestMapping(value = "/people.json", method = RequestMethod.POST)
public String create(@ModelAttribute("person") Person person, BindingResult result) {
personService.create(person);
return "{\"person\": "+person+"}";
}
@ResponseBody
@RequestMapping(value = "/people/{personId}.json", method = RequestMethod.PUT)
public String update(@PathVariable("personId") Integer personId, @ModelAttribute("person") Person person, BindingResult result) {
personService.update(personId, person);
return "{\"person\": "+person+"}";
}
@ResponseBody
@RequestMapping(value = "/people/{personId}.json", method = RequestMethod.DELETE)
public String delete(@PathVariable("personId") Integer personId) {
personService.delete(personId);
return "{\"status\": \"ok\", \"message\": \"\"}";
}
}
以下是我服务的代码:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.model.Person;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;
@Service
public class PersonServiceImpl implements PersonService {
@PersistenceContext
EntityManager em;
@Transactional
public List<Person> all() {
CriteriaQuery<Person> c = em.getCriteriaBuilder().createQuery(Person.class);
c.from(Person.class);
return em.createQuery(c).getResultList();
}
@Transactional
public Person find(Integer id) {
Person person = em.find(Person.class, id);
return person;
}
@Transactional
public void create(Person person) {
em.persist(person);
}
public void update(Integer id, Person person) {
// TODO: How to implement this?
}
@Transactional
public void delete(Integer id) {
Person person = em.find(Person.class, id);
if (null != person) {
em.remove(person);
}
}
}
所以,对于Spring,那里的hibernate专家,完成我需要的最好的方法是什么?资源更新仅更新实际更改的属性
也很重要谢谢,
答案 0 :(得分:1)
更改PersonService
更新方法签名,使其返回Person
,同样,您不需要单独的id
,只需使用Person
对象即可身份证。他们实现这样的方法:
public Person update(Person person) {
// you might want to validate the person object somehow
return em.merge(person);
}
同时更新您的网络服务图层。要么更改它以便personId
不再存在,要么保留它并使用它设置Person
ID:
public String update(@PathVariable("personId") Integer personId,
@ModelAttribute("person") Person person, BindingResult result) {
person.setId(personId);
Person updated = personService.update(person);
// You may want to use a JSON library instead of overriding toString.
return "{\"person\": " + updated + "}";
}
一个小问题,合并也可能会持续存在新实体。因此,如果您想确保update
仅更新现有的id
,请将其正文更改为:
public Person update(Person person) {
if(em.find(Person.class, person.getId()) == null) {
throw new IllegalArgumentException("Person " + person.getId()
+ " does not exists");
}
return em.merge(person);
}
资源更新仅更新实际更改的属性
也很重要
如果希望hibernate只更新JSON对象和数据库之间不同的属性,dynamicUpdate
上有selectBeforeUpdate
和@org.hibernate.annotations.Entity
属性的便捷组合(请查看{ {3}})。只有在您确实需要行为时才启用此功能(这是非标准行为,可能会降低性能)。
@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = true)
在Hibernate 4.0上这些已弃用的属性,您可以使用单独的注释:
@DynamicUpdate
@SelectBeforeUpdate