Blog top image

Partial data update in Spring Boot


পার্শিয়াল আপডেট কি?

আপনি যদি স্প্রিং - হাইবারনেট জগতের বাসিন্দা হন, তাহলে জেনে থাকবেন যে, যখন আমরা রেপিজিটরিতে সেভ মেথড কল করি, সে তখন তাকে একটা আস্ত অবজেক্ট দেয়া লাগে। সে তখন পুরা অবজেক্টের উপর আপডেট চালায়।যদি আপনার অবজেক্ট ছোট হয় এবং বার বার আপডেট করার দরকার না হয়,তাহলে ঠিক আছে। কিন্ত অবজেক্ট যদি অনেক বড় হয় এবং আপনি সামান্য একটা ফিল্ড আপডেট করতে চাচ্ছেন তাহলে জিনিষটা একটু বেশিই হয়ে যায়।আবার আরো বেশি হয়ে যায় যখন অবজেক্টের কোন একটা ফিল্ড বারবার আপডেট করতে হয়।


বাস্তব উদাহরণ

ব্লগের পোস্ট একটা বেশ বড় অবজেক্ট। আবার লেখক যখন পোস্ট লিখেন তখন তলে তলে একটা সময়ের ব্যবধানে পোস্ট বডি আপডেট করা উচিত। কেননা, কেউ এক ঘন্টা সময় ব্যয় করে একটা পোস্ট লিখে সাবমিট করার সময় কোন কারণে যদি পোস্ট সেভ না হয়, এর থেকে খারাপ ঘটনা আর হতে পারে না। তাহলে চলুন দেখা যাক কিভাবে এই সমস্যার সমাধান করা যায়।


ফ্রন্টএন্ড

পোস্ট  মডেল পরিবর্তন কাউন্ট করার জন্য একটা কাউন্টার এবং কাউন্টারের মান একটা পর্যায়ের গেলেই আপডেট সার্ভিস কল হবে। আমার কাছে এটা বেশি এলিগেন্ট সুলুশন মনে হয়েছে।

১. কুইলে এডিটরে(রিচ টেক্সট এডিটর) মডেল চেঞ্জ মেথড ব্যবহার করা হয়েছে

<quill-editor
        (ngModelChange)="updateBody()"
        [(ngModel)]="post.body"
        [styles]="{height: '300px'}">
</quill-editor>  


২. কাউন্টার ২০ হলেই বডি আপডেট হয়ে যাবে

updateBody() {
  this.bodyCounter++;
  if ( this.post.id && this.bodyCounter === 20 ) {
    const data = new Post();
    data.id = this.post.id;
    data.body = this.post.body;
    this.adminPostService.partialUpdate(data)
        .subscribe( resp => {
          console.log('Body updated');
          this.bodyCounter = 0;
        });
  }
}



৩. সার্ভিস

partialUpdate(post): Observable<any> {
  return this.http.put(ApiUrl.adminPosts  + 'partial-update/', post);
}



ব্যাকএন্ড

আপনার অবজেক্টের বেশ করেকটা ফিল্ড থাকতে পারে, যাদেরকে আপনি পার্শিয়ালি আপডেট করতে চান। তাই সবচেয়ে ভালো হয়একটা DTO লিখে ফেললে। তারপর সার্ভিস থেকে আলাদা আলাদা রিপোজিটরি মেথড ব্যবহার করলেই হয়ে যাবে। কিন্তু একাধিক ফিলড থাকলে কোন ফিল্ড আপডেট করতেছি তার জন্য কন্ডিশন না লিখে জাভা ৮ এর অপশনাল এর চমৎকার ব্যবহার করা যায়।


১. পার্শিয়াল আপডেট এর জন্য DTO সাথে অপশনাল পাবলিক মেথড

@Data
public class PostPartialDto {

    @NotNull
    private String id;

    private String body;

    private Integer position;

    public Optional<String> body() {
        return Optional.ofNullable(body);
   }

    public Optional<Integer> position() {
        return Optional.ofNullable(position);
    }
}


২. সার্ভিস

@Override
public Optional<Integer> partialUpdate(PostPartialDto postPartialDto) {
   
     postPartialDto.body()
            .map( body -> postRepository.updateBody(postPartialDto.getId(), body));

     postPartialDto.position()
             .map( position -> postRepository.updatePosition(postPartialDto.getId(), position));

     return Optional.of(1);
}



৩. সর্বশেষ স্প্রিং ডাটার পার্শিয়াল আপডেট কুয়েরি

@Modifying
@Transactional
@Query("update Post p set p.position = :position where p.id = :id")
Integer updatePosition(@Param("id") String id, @Param("position") Integer position);

@Modifying
@Transactional
@Query("update Post p set p.body = :body where p.id = :id")
Integer updateBody(@Param("id") String id, @Param("body") String body);