স্প্রিং ডেটার মঙ্গো টেম্পলেট এবং মঙ্গোরেপসিতির মধ্যে পার্থক্য কী?


102

আমার একটি অ্যাপ্লিকেশন লিখতে হবে যা দিয়ে আমি স্প্রিং-ডেটা এবং মংডোব ব্যবহার করে জটিল প্রশ্নগুলি করতে পারি। আমি মঙ্গোরিপোসিটোরি ব্যবহার করে শুরু করেছিলাম তবে উদাহরণ খুঁজে পেতে বা সিনট্যাক্সটি বুঝতে আসলে জটিল প্রশ্নগুলির সাথে লড়াই করেছি।

আমি এই জাতীয় প্রশ্নের কথা বলছি:

@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
    List<User> findByEmailOrLastName(String email, String lastName);
}

বা JSON ভিত্তিক প্রশ্নের ব্যবহার যা পরীক্ষার এবং ত্রুটির দ্বারা চেষ্টা করেছি কারণ আমি সিনট্যাক্সটি সঠিকভাবে পাই না। এমনকি মোংডব ডকুমেন্টেশন পড়ার পরেও (ভুল সিনট্যাক্সের কারণে অ-কার্যকারী উদাহরণ)।

@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
    @Query("'$or':[{'firstName':{'$regex':?0,'$options':'i'}},{'lastName':{'$regex':?0,'$options':'i'}}]")
    List<User> findByEmailOrFirstnameOrLastnameLike(String searchText);
} 

সমস্ত ডকুমেন্টেশন পড়ার পরে মনে হয় এটি mongoTemplateতখনকার চেয়ে আরও ভাল নথিভুক্ত MongoRepository। আমি নিম্নলিখিত ডকুমেন্টেশন উল্লেখ করছি:

http://static.springsource.org/spring-data/data-mongodb/docs/current/references/html/

আপনি কি আমাকে আরও সুবিধাজনক এবং ব্যবহার করার জন্য শক্তিশালী বলতে পারেন? mongoTemplateবা MongoRepository? দু'জনেই কি একই রকম পরিপক্ক বা এর মধ্যে একটির কি অন্য বৈশিষ্ট্যের অভাব রয়েছে?

উত্তর:


136

"সুবিধাজনক" এবং "ব্যবহারের ক্ষমতাবান" কিছুটা ডিগ্রির লক্ষ্যের সাথে বিরোধী। সংগ্রহশালা টেমপ্লেটগুলির তুলনায় অনেক বেশি সুবিধাজনক তবে অবশ্যই পরবর্তীটি আপনাকে কী কার্যকর করতে হবে তার উপর আরও সূক্ষ্ম নিয়ন্ত্রণ দেয়।

সংগ্রহস্থল প্রোগ্রামিং মডেলটি একাধিক স্প্রিং ডেটা মডিউলগুলির জন্য উপলভ্য হওয়ায় আপনি স্প্রিং ডেটা মঙ্গোডিবি রেফারেন্স ডক্সের সাধারণ বিভাগে এর জন্য আরও গভীরতর ডকুমেন্টেশন পাবেন ।

টিএল; ডিআর

আমরা সাধারণত নিম্নলিখিত পদ্ধতির সুপারিশ করি:

  1. সংগ্রহস্থল বিমূর্তি দিয়ে শুরু করুন এবং কোয়েরি ডেরাইভেশন মেকানিজম বা ম্যানুয়ালি সংজ্ঞায়িত ক্যোয়ারীগুলি ব্যবহার করে সাধারণ প্রশ্নগুলি ঘোষণা করুন।
  2. আরও জটিল প্রশ্নের জন্য, সংগ্রহস্থলে ম্যানুয়ালি প্রয়োগ করা পদ্ধতি যুক্ত করুন (এখানে ডকুমেন্টেড হিসাবে)। বাস্তবায়ন ব্যবহারের জন্য MongoTemplate

বিশদ

আপনার উদাহরণের জন্য এটি দেখতে এরকম কিছু দেখাচ্ছে:

  1. আপনার কাস্টম কোডের জন্য একটি ইন্টারফেস সংজ্ঞা দিন:

    interface CustomUserRepository {
    
      List<User> yourCustomMethod();
    }
    
  2. এই শ্রেণীর জন্য একটি বাস্তবায়ন যুক্ত করুন এবং আমরা ক্লাসটি খুঁজে পেতে পারি তা নিশ্চিত করার জন্য নামকরণের সম্মেলনটি অনুসরণ করুন।

    class UserRepositoryImpl implements CustomUserRepository {
    
      private final MongoOperations operations;
    
      @Autowired
      public UserRepositoryImpl(MongoOperations operations) {
    
        Assert.notNull(operations, "MongoOperations must not be null!");
        this.operations = operations;
      }
    
      public List<User> yourCustomMethod() {
        // custom implementation here
      }
    }
    
  3. এখন আপনার বেস ভান্ডার ইন্টারফেসটি কাস্টমটিকে প্রসারিত করতে দিন এবং পরিকাঠামো স্বয়ংক্রিয়ভাবে আপনার কাস্টম প্রয়োগটি ব্যবহার করবে:

    interface UserRepository extends CrudRepository<User, Long>, CustomUserRepository {
    
    }
    

এইভাবে আপনি পছন্দটি পাবেন: কেবলমাত্র ঘোষণা করা সহজ UserRepositoryযে সমস্ত কিছু ম্যানুয়ালি প্রয়োগ করা হয় তার মধ্যে প্রবেশ করে CustomUserRepository। কাস্টমাইজেশন বিকল্পগুলি এখানে নথিভুক্ত করা হয়


4
হাই অলিভার, এটি আসলে কাজ করে না। বসন্ত-ডেটা কাস্টম নাম থেকে একটি কোয়েরি স্বয়ংক্রিয়ভাবে উত্পন্ন করার চেষ্টা করে। আপনার কাস্টমমেথোদ ()। এটি বলবে "আপনার" ডোমেন শ্রেণিতে কোনও বৈধ ক্ষেত্র নয়। আমি ম্যানুয়ালটি অনুসরণ করেছি এবং আপনি কীভাবে এটি বসন্ত-ডেটা-জেপিএ-উদাহরণগুলি করছেন তা ডাবল পরীক্ষা করে দেখেছি। ভাগ্য নেই. স্প্রিং-ডেটা সর্বদা স্বয়ং সংগ্রহ করার চেষ্টা করে যত তাড়াতাড়ি আমি কাস্টম ইন্টারফেসটি সংগ্রহস্থল শ্রেণিতে প্রসারিত করি। পার্থক্যটি হ'ল আমি মংগেরোপোসিটোরি ব্যবহার করছি না ক্রুডেপোসিটোরি নয়, কারণ আমি এখনই আইট্রেটারদের সাথে কাজ করতে চাই না। যদি আপনার কোনও ইঙ্গিত থাকে তবে এটি প্রশংসিত হবে।
ক্রিস্টোফার আর্মস্ট্রং

11
সর্বাধিক সাধারণ ভুলটি প্রয়োগকরণ ক্লাসের নাম রাখা ভুল: যদি আপনার বেস রেপো ইন্টারফেস বলা হয় YourRepository, বাস্তবায়ন শ্রেণীর নামকরণ করতে হবে YourRepositoryImpl। এটাই কি? যদি তাই হয় তবে আমি গিটহাবের মতো নমুনা প্রকল্প বা এর মতো এক
নজরে দেখে খুশি

4
হাই অলিভার, আপনি ধরে নিয়েছেন বলে ইমপ্ল ক্লাসটি ভুল নামকরণ করেছিল। আমি নামটি সামঞ্জস্য করেছি এবং এটি এখন এটির মতো কাজ করছে বলে মনে হচ্ছে। আপনার মতামতের জন্য অনেক ধন্যবাদ। বিভিন্ন ধরণের ক্যোয়ারী বিকল্পগুলি এভাবে ব্যবহার করতে সক্ষম হওয়া সত্যিই দুর্দান্ত। মাধ্যমে ভাল চিন্তা!
ক্রিস্টোফার আর্মস্ট্রং

এই উত্তরটি এত পরিষ্কার নয়। এই উদাহরণ দিয়ে সবকিছু করার পরে আমি এই ইস্যুতে পড়ে: stackoverflow.com/a/13947263/449553 । সুতরাং নামকরণ কনভেনশন যেমন এই উদাহরণ থেকে দেখায় তার চেয়ে আরও কঠোর।
মিশানজেল

4
# 2 এ বাস্তবায়ন শ্রেণীর নাম দেওয়া হয়েছে ভুল: এটি হওয়া উচিত CustomUserRepositoryএবং হওয়া উচিত নয় CustomerUserRepository
কোট্টা

27

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

পরিবর্তে, MongoTemplateরুটটিতে যান এবং আপনার নিজস্ব ডেটা অ্যাক্সেস স্তর তৈরি করুন যা আপনাকে স্প্রিং প্রোগ্রামারগুলির মুখোমুখি হওয়া কনফিগারেশন দুঃস্বপ্ন থেকে মুক্তি দেয়। MongoTemplateপ্রকৌশলী প্রকৌশলী যারা তাদের নিজস্ব ক্লাস এবং মিথস্ক্রিয়া আরামদায়ক আরামদায়ক যেহেতু এখানে অনেক নমনীয়তা রয়েছে for কাঠামোটি এরকম কিছু হতে পারে:

  1. এমন একটি MongoClientFactoryক্লাস তৈরি করুন যা অ্যাপ্লিকেশন পর্যায়ে চলবে এবং আপনাকে একটি MongoClientঅবজেক্ট দেবে। আপনি এটি একক হিসাবে ব্যবহার করতে পারেন বা একটি এনুম সিঙ্গলটন ব্যবহার করতে পারেন (এটি থ্রেডটি নিরাপদ)
  2. ডেটা অ্যাক্সেস বেস ক্লাস তৈরি করুন যা থেকে আপনি প্রতিটি ডোমেন অবজেক্টের জন্য ডেটা অ্যাক্সেস অবজেক্টের উত্তরাধিকারী হতে পারেন)। বেস ক্লাসটি মংগেম্প্লেট অবজেক্ট তৈরির জন্য একটি পদ্ধতি প্রয়োগ করতে পারে যা আপনি শ্রেণিবদ্ধ পদ্ধতিগুলি সমস্ত ডিবি অ্যাক্সেসের জন্য ব্যবহার করতে পারেন
  3. প্রতিটি ডোমেন অবজেক্টের জন্য প্রতিটি ডেটা অ্যাক্সেস শ্রেণি মৌলিক পদ্ধতিগুলি প্রয়োগ করতে পারে বা আপনি এটিকে বেস শ্রেণিতে প্রয়োগ করতে পারেন
  4. কন্ট্রোলার পদ্ধতিগুলি প্রয়োজন অনুসারে ডেটা অ্যাক্সেস ক্লাসে পদ্ধতিগুলিতে কল করতে পারে।

হাই @ রমেশপা আমি কি একই প্রকল্পে মঙ্গো টেম্পলেট এবং সংগ্রহশালা দুটোই ব্যবহার করতে পারি? .. এটি কি সম্ভব?
গৌরাঙ্গ

4
আপনি যে মঙ্গো টেম্পলেটটি প্রয়োগ করেছিলেন তা ডিপোর সাথে রিপোজিটরির সাথে সংযোগের চেয়ে আলাদা সংযোগ থাকবে। পারমাণবিকতা একটি সমস্যা হতে পারে। এছাড়াও আপনার যদি সিকোয়েন্সিংয়ের প্রয়োজন হয় তবে আমি একটি থ্রেডে দুটি পৃথক সংযোগ ব্যবহার করার পরামর্শ দেব না
রামেশপা

27

বহু-থ্রেড পরিবেশে আপডেট সম্পর্কিত এফডাব্লুআইডাব্লু:

  • MongoTemplateউপলব্ধ "পারমাণবিক" আউট-অফ-বক্স অপারেশন updateFirst , updateMulti, findAndModify, upsert... যা আপনি একটি একক অভিযানে একটি নথি সংশোধন করার অনুমতি দেয়। Updateএই পদ্ধতি দ্বারা ব্যবহৃত অবজেক্ট এছাড়াও আপনি শুধুমাত্র প্রাসঙ্গিক ক্ষেত্রের লক্ষ্য করতে পারবেন
  • MongoRepositoryশুধুমাত্র আপনি দেয় মৌলিক টি ককটেলের অপারেশন find , insert, save, delete, ধারণকারী POJOs সঙ্গে যা কাজ সব ক্ষেত্র । এটি আপনাকে বেশ কয়েকটি পদক্ষেপে ডকুমেন্টগুলি আপডেট করতে বাধ্য করে (১. findডকুমেন্ট আপডেট করার জন্য, ২. প্রত্যাবর্তিত POJO থেকে প্রাসঙ্গিক ক্ষেত্রগুলি সংশোধন করুন, এবং তারপরে ৩. saveএটি), বা হাত ব্যবহার করে আপনার নিজের আপডেট প্রশ্নগুলি সংজ্ঞায়িত করুন @Query

একাধিক-থ্রেড পরিবেশে যেমন জাভা ব্যাক-এন্ডের সাথে বেশ কয়েকটি রিস্টের শেষ পয়েন্ট রয়েছে, একক পদ্ধতিতে আপডেটগুলি একে অপরের পরিবর্তনকে ওভাররাইট করে দুটি সমবর্তী আপডেটের সম্ভাবনা হ্রাস করার জন্য go

উদাহরণ: এর মতো একটি দস্তাবেজ দেওয়া হয়েছে: { _id: "ID1", field1: "a string", field2: 10.0 }এবং দুটি পৃথক থ্রেড একযোগে এটি আপডেট করা হচ্ছে ...

সঙ্গে MongoTemplateএটা ভালো কিছুটা দেখাবে:

THREAD_001                                                      THREAD_002
|                                                               |
|update(query("ID1"), Update().set("field1", "another string")) |update(query("ID1"), Update().inc("field2", 5))
|                                                               |
|                                                               |

এবং নথির চূড়ান্ত অবস্থা সবসময় { _id: "ID1", field1: "another string", field2: 15.0 }যেহেতু প্রতিটি থ্রেড কেবল একবার ডিবিতে অ্যাক্সেস করে এবং কেবলমাত্র নির্দিষ্ট ক্ষেত্রটি পরিবর্তিত হয়।

একই ক্ষেত্রে একই পরিস্থিতি MongoRepositoryদেখতে হবে:

THREAD_001                                                      THREAD_002
|                                                               |
|pojo = findById("ID1")                                         |pojo = findById("ID1")
|pojo.setField1("another string") /* field2 still 10.0 */       |pojo.setField2(pojo.getField2()+5) /* field1 still "a string" */
|save(pojo)                                                     |save(pojo)
|                                                               |
|                                                               |

এবং চূড়ান্ত নথিটি হয় { _id: "ID1", field1: "another string", field2: 10.0 }বা { _id: "ID1", field1: "a string", field2: 15.0 }নির্ভর করে যে saveঅপারেশনটি সর্বশেষ ডিবিতে আঘাত করে।
(দ্রষ্টব্য: এমনকি আমরা মন্তব্যে প্রস্তাবিত স্প্রিং ডেটার @Versionটীকাটি ব্যবহার করলেও, খুব বেশি পরিবর্তন হবে না: saveঅপারেশনগুলির মধ্যে একটিটি নিক্ষেপ করবে OptimisticLockingFailureExceptionএবং চূড়ান্ত নথিটি উভয়ের পরিবর্তে কেবল একটি ক্ষেত্র আপডেট করা হলেও উপরের একটি হতে পারে। )

সুতরাং আমি বলব যে MongoTemplateএটি একটি ভাল বিকল্প , যদি না আপনার কাছে খুব বিস্তৃত POJO মডেল থাকে বা MongoRepositoryকোনও কারণে কাস্টম প্রশ্নের সক্ষমতা প্রয়োজন হয় না।


ভাল পয়েন্ট / উদাহরণ। তবে আপনার বর্ণের অবস্থার উদাহরণ এবং অনাকাঙ্ক্ষিত ফলাফলটি সেই পরিস্থিতিটি রোধ করতে @ সংস্করণ ব্যবহার এড়ানো যেতে পারে।
ম্যাডব্রেকস

@ ম্যাডব্র্যাকস কীভাবে আপনি এটি অর্জন করবেন তার কোনও সংস্থান সরবরাহ করতে পারেন? কোন অফিসিয়াল ডক সম্ভবত?
কার্তিকেইয়ান

@Version টীকা সম্পর্কে স্প্রিং ডাটা দস্তাবেজ: docs.spring.io/spring-data/mongodb/docs/current/reference/html/...
করিম তৌফিক

4
@ ম্যাডব্র্যাকস এটিকে নির্দেশ করার জন্য ধন্যবাদ। হ্যাঁ, @Versionদ্বিতীয় থ্রেডটি প্রথম দ্বারা সংরক্ষিত ডেটা ওভাররাইট করে "এড়ানো" হবে - এই অর্থে যে এটি আপডেটটি বাতিল করবে এবং OptimisticLockingFailureExceptionপরিবর্তে একটি নিক্ষেপ করবে । সুতরাং আপনি যদি আপডেটটি সফল হতে চান তবে আপনাকে আবার চেষ্টা করার পদ্ধতি প্রয়োগ করতে হবে। মঙ্গো টেম্পলেট আপনাকে পুরো দৃশ্য এড়াতে দেয় allows
ওয়ালেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.