2016-02-12 17 views
9

私のコントローラどのように変更された属性のみを更新するために - 春の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 
} 

DAO

@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); 
} 

このメソッドは動作しますが、それは私のためにかなり醜いです。ユーザーがビュー内のファーストネームフィールドを変更したばかりで、ファーストネームを設定するために関数を呼び出すためにコードを適用するにはどうすればよいですか?

フィールドに変更があることを通知するObserverパターンのようなものはありますか?

+0

rをハイバーネーションで使用していますか? – Musaddique

+0

はい私はより正確になるために、春のブート - スターター - データ - jpaを使用しています – melkir

+0

私の下の答えを参照してくださいdynamicUpdateを使用して= trueを参照してください。変更された値のみが更新されます。 – Musaddique

答えて

3

あなたのコードは次のように動作します:

ユーザーがuser entityのデータを変更したい。フロントエンドでは、firstname、lastnameなどの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%の質問には答えませんが、まさに彼が探し求めた解決策でした。彼は 'updateUser'の "醜い"メソッドを望んでいないからです。 downvoteが正当化されているかどうかは分かりません。 – Patrick

1

あなたが休止状態を使用している場合は、コードhibenrate 4 +これら

@DynamicInsert(true) 
@DynamicUpdate(true) 
を使用するための

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

以下のようなデシベル

でのみ更新のフィールドを更新します休止状態dynamicUpdate = true内の1つの属性があります

+0

注釈はすべて私が必要ですか?私のupdateUserメソッドはまだすべてのフィールドを設定しているので、私はこれを求めています。しかし、これは "。save()"メソッドのデータベースクエリを減らすことに同意します。 – melkir

+0

いいえ、更新されたデータのみを設定する方法はありません。ユーザーはすべてのデータを持っている必要があるからです。最終的にデータベースで更新されるため、休止状態ではすべてのデータが必要です。それ以外の場合は、ユーザーが属性値を持たない場合は、休止状態になります。 – 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> 

そして再び、あなたのDAOで、あなたはnullをチェック

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

親切にノートを置くことができ、このコードはテストされ、downvotesを待っていません。

関連する問題