2016-02-12 43 views
9

我控制器如何只更新屬性已經改變 - Spring MVC的

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET) 
public String updateUserById(@PathVariable("id") Long id, Model model) { 
    User user = userRepository.findOne(id); 
    model.addAttribute(user); 
    return "admin/editUser"; 
} 

@RequestMapping(value = "/user/{id}", method = RequestMethod.POST) 
@ResponseBody 
public String updateUserById(@PathVariable("id") Long id, @ModelAttribute User user) { 
    userRepository.updateUser(id, user); // with a try catch 
} 

清道

@Override 
public void updateUser(Long id, User user) { 
    User userDB = userRepository.findOne(id); 
    userDB.setFirstName(user.getFirstName()); 
    userDB.setLastName(user.getLastName()); 
    userDB.setEmail(user.getEmail()); 
    userDB.setUsername(user.getUsername()); 
    userRepository.save(userDB); 
} 

這種方法的作品,但它是相當醜陋的我。假設用戶剛剛更改了視圖中的名字字段,我如何才能調整我的代碼以僅調用函數來設置名字?

有點像觀察者模式來通知字段有變化?

+0

使用休眠? – Musaddique

+0

是的,我使用休眠,spring-boot-starter-data-jpa更準確 – melkir

+0

看到我的下面的答案use dynamicUpdate = true。它只會更新僅更改的值。 – Musaddique

回答

3

我想你的代碼是這樣工作的:

用戶想要更改他的某些數據user entity。在前端的意思是你已經把他的所有條目從DB的用戶表中顯示出來,比如名字,姓氏等等。

例如,用戶更改了自己的名字並點擊保存按鈕。您的控制器接收用戶實體,包括user.id,新的名字和所有舊的設置值。如果您的代碼像這樣工作,您可以輕鬆地將用戶實體save()。沒有必要先從DB獲取用戶。

所以才做這樣的:

@Override 
public void updateUser(User user) { 
    userRepository.save(user); 
} 

Repository知道用戶實體的ID和剛剛更新完整的實體。

而對於你沒有的Id在用戶實體的原因使用ID從您的控制器是這樣的:

​​
+0

感謝您的解釋! – melkir

+0

它不回答這個問題。問題是:「如何僅更新已更改的屬性」。答案仍然是更新userRepository.save(...)中的屬性。它只是不做套,但背後的數據庫設置將發生。 例如:user.firstName ='lolo',用戶想要更改user.lastName ='koko'。但@trudy攔截它並更改名字。更新將改變 – lolo

+0

@ lolo也許它不回答100%的問題,但它正是他搜索的解決方案。因爲他不需要「更新用戶」的「醜陋」方法。所以不知道downvote是否合理。 – Patrick

1

如果你是使用Hibernate則處於休眠dynamicUpdate = true一個屬性,該屬性將只更新更新分貝

領域,如下面的代碼

@Entity 
@Table(name = "User") 
@org.hibernate.annotations.Entity(
     dynamicUpdate = true 
) 
public class User 

爲hibenrate 4 +使用這些

@DynamicInsert(true) 
@DynamicUpdate(true) 
+0

註釋是我需要的嗎?我問這是因爲我的updateUser方法仍然設置所有字段。但我同意這會減少「.save()」方法的數據庫查詢。 – melkir

+0

沒有辦法只設置更新的數據。因爲用戶應該擁有所有數據。因爲最後它會在數據庫中更新,所以hibernate需要所有數據,否則如果用戶沒有屬性值,hibernate將更新爲null。 – Musaddique

-1

假設這是你的用戶。

@Entity 
public class User{ 
    String userName; 
} 

然後在您的jsp頁面中,您可以執行類似下面的操作。

<input type = "text" name = "userName" value = "${userName}" data-changed = "false" class="form_elem"/> 

<script> 
    $(".form_elem").change(function(){ 
     $(this).data("changed", true); 
    }); 

    function submit(){ 
     $(".form_elem").each(function(){ 
      if($(this).data("changed") == false){ 
       $(this).val(""); 
      } 
     }); 
     //Do submit here 
    } 
</script> 

而且又在你的道,你可以把空校驗

@Override 
public void updateUser(Long id, User user) { 
    User userDB = userRepository.findOne(id); 
    if(user.getFirstName() != null){ 
     userDB.setFirstName(user.getFirstName()); 
    } 
} 

請注意,這段代碼沒有進行測試,並等待downvotes。

相關問題