JPA এবং হাইবারনেট ব্যবহার করার সময় JOIN এবং JEIN FETCH এর মধ্যে পার্থক্য কী


182

দয়া করে আমাকে নিয়মিত যোগদান এবং কোথায় যোগ দিতে হবে তা বুঝতে আমাকে সহায়তা করুন।

উদাহরণস্বরূপ, আমাদের যদি এই দুটি প্রশ্ন থাকে

FROM Employee emp
JOIN emp.department dep

এবং

FROM Employee emp
JOIN FETCH emp.department dep

তাদের মধ্যে কি কোনও পার্থক্য আছে? যদি হ্যাঁ, কোনটি কখন ব্যবহার করবেন?


2
আপনি এখানে লিঙ্কটি পড়তে পারেন 14.3 পড়ুন। সমিতি এবং যোগ দেয়
অ্যাংগা

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

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

ডক হান্টে সহায়তা করতে Strate কৌশলগুলি
এডি বি

1
@ শমিরাআনুরঙ্গ আমি মনে করি সেক্ষেত্রে আপনার একটি বাম বাহ্যিক যোগদানের প্রয়োজন হবে।
আব্বাস

উত্তর:


179

এই দুটি প্রশ্নের মধ্যে, আপনি কমপক্ষে একটি বিভাগ সম্পর্কিত সমস্ত কর্মচারীদের জিজ্ঞাসা করতে JOIN ব্যবহার করছেন।

তবে, পার্থক্যটি হ'ল: প্রথম ক্যোয়ারিতে আপনি কেবলমাত্র হাইবারনেটের জন্য কর্মচারীদের ফিরিয়ে দিচ্ছেন। দ্বিতীয় ক্যোয়ারিতে আপনি কর্মচারী এবং সংশ্লিষ্ট সমস্ত বিভাগ ফিরিয়ে দিচ্ছেন ।

সুতরাং, আপনি যদি দ্বিতীয় কোয়েরিটি ব্যবহার করেন তবে প্রতিটি কর্মচারীর বিভাগগুলি দেখতে আপনাকে নতুন ডাটাবেসটি হিট করতে হবে না।

আপনি যখন নিশ্চিত হন যে আপনি প্রতিটি কর্মচারীর বিভাগের প্রয়োজন হবে তখন আপনি দ্বিতীয় কোয়েরিটি ব্যবহার করতে পারেন। আপনার যদি বিভাগের প্রয়োজন না হয় তবে প্রথম ক্যোয়ারীটি ব্যবহার করুন।

আমি আপনাকে এই লিঙ্কটি পুনরুদ্ধারের পুনরুদ্ধার করতে চাই যদি আপনার কিছু WHERE শর্ত প্রয়োগ করতে হয় (যা আপনার সম্ভবত প্রয়োজন হবে): জেপিএ 2 ক্রিটারিয়াকোয়ারি হিসাবে "যেখানে" সহ "জেপি" কীভাবে সঠিকভাবে প্রকাশ করবেন?

হালনাগাদ

যদি আপনি ব্যবহার না করেন fetchএবং বিভাগগুলি ফেরত দেওয়া অব্যাহত থাকে, কারণ কর্মচারী এবং বিভাগের (ক @OneToMany) এর মধ্যে আপনার ম্যাপিং সেট করা রয়েছে FetchType.EAGER। এই ক্ষেত্রে, যে কোনও এইচকিউএল (সাথে fetchবা নেই) কোয়েরিটি FROM Employeeসমস্ত বিভাগ নিয়ে আসবে। মনে রাখবেন যে সমস্ত ম্যাপিং * টুন ( @ManyToOneএবং @OneToOne) ডিফল্টরূপে ইগর হয়।


1
কোন প্রতিক্রিয়া হবে যদি আমরা আনয়ন ছাড়াই বিবৃতি কার্যকর করি এবং ফলাফল পাই। তাহলে সেশনের মধ্যে আমরা কি বিভাগে চিকিৎসা করব?
gstackoverflow

1
@ জিস্ট্যাকওভারফ্লো, হ্যাঁ
ধেরিক

আমি সম্পর্কের উভয় পক্ষেই অলস আনার সাথে নেটিভ ক্যোয়ারী ব্যবহার করি তবে তবুও সন্তানের সম্পর্কের স্তরক্রম লোড হয়।
বাদামচি

উল্লেখযোগ্য যে উল্লেখ fetchকরতে হবে (যদি আমাদের উদাহরণ ব্যবহার করে) আপনি কোনও ডিপার্টমেন্টের অ্যাট্রিবিউট দ্বারা অর্ডার করতে চান। অন্যথায়, (কমপক্ষে পিজির জন্য বৈধ) আপনি পেতে পারেনERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
লম্বা

60

মধ্যে এই লিঙ্কে আমি মন্তব্যে আগে উল্লেখ করেছে, এই অংশ পড়ুন:

একটি "আনা" যোগদানের ফলে অ্যাসোসিয়েশন বা মানগুলির সংগ্রহগুলি একটি একক নির্বাচন ব্যবহার করে তাদের পিতামাত্ত বস্তুগুলির সাথে আরম্ভ করার অনুমতি দেয়। এটি সংগ্রহের ক্ষেত্রে বিশেষভাবে কার্যকর। এটি কার্যকরভাবে সমিতিগুলি এবং সংগ্রহের জন্য ম্যাপিং ফাইলটির বাইরের যোগদান এবং অলস ঘোষণাকে ওভাররাইড করে

সত্তার অভ্যন্তরের কোনও সংগ্রহের জন্য (ফ্যাচ = ফেচটাইপ.লাজি) সম্পত্তি থাকলে এই "জয়েন্ট ফিচ" এর প্রভাব থাকবে।

এবং এটি কেবলমাত্র "যখন জিজ্ঞাসাটি হওয়া উচিত" এর পদ্ধতিটিই কার্যকর। আর আপনার কাছে জানতে হবে এই :

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

সমিতিটি কখন আনা হবে -> আপনার "FETCH" প্রকার

এটি কীভাবে আনা হয় -> যোগদান / নির্বাচন / সাব-সিলেক্ট / ব্যাচ

আপনার ক্ষেত্রে, FETCH কেবল তখনই কার্যকর হবে যদি আপনার কর্মচারীর অভ্যন্তরে সেট হিসাবে বিভাগ থাকে, সত্তায় এটির মতো কিছু:

@OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;

আপনি যখন ব্যবহার

FROM Employee emp
JOIN FETCH emp.department dep

আপনি পাবেন empএবং emp.dep। যখন আপনি আনতে ব্যবহার emp.depকরেননি আপনি এখনও পেতে পারেন তবে হাইবারনেট বিভাগের সেটটি পেতে ডাটাবেজে অন্য একটি নির্বাচন প্রক্রিয়াজাত করবে।

সুতরাং এটি কেবল পারফরম্যান্স টিউন করার বিষয়, আপনি একক ক্যোয়ারিতে (উত্সাহিত হওয়া) সমস্ত ফলাফল (আপনার এটি প্রয়োজন বা না হওয়া) পেতে চান বা যখন আপনার প্রয়োজন হবে (অলস আনতে হবে) তবে এটি অনুসন্ধান করতে চান।

আপনার যখন একটি সিলেক্ট (একটি বড় ক্যোরি) দিয়ে ছোট ডেটা পাওয়ার দরকার হয় তখন আগ্রহী আনতে ব্যবহার করুন। বা আপনার কীসের পরে (অনেক ছোট ক্যোয়ারী) প্রয়োজন তা জিজ্ঞাসা করার জন্য অলস আনয়ন ব্যবহার করুন।

আনতে যখন ব্যবহার করুন:

  • আপনি যে সত্তাটি পেতে যাচ্ছেন তার ভিতরে কোনও বড় বিনা বিন্যাসের সংগ্রহ / সেট নেই

  • অ্যাপ্লিকেশন সার্ভার থেকে ডাটাবেস সার্ভারে খুব দূরের যোগাযোগ এবং দীর্ঘ সময়ের প্রয়োজন

  • আপনার এটিতে অ্যাক্সেস (না যখন আপনি যে সংগ্রহ আধুনিক প্রয়োজন হতে পারে বাহিরে এর লেনদেনের পদ্ধতি / বর্গ)


আমি সবেমাত্র আপডেট করা প্রশ্নে লিখেছি এমন প্রশ্নের জন্য আপনি এটি ব্যাখ্যা করতে পারেন?
আব্বাস

দরকারী বিবেচনা: "আপনি যে সত্তাটি পেতে
যাচ্ছেন তার

কর্মচারীর অভ্যন্তরীণ বিভাগগুলি যদি একটি Listপরিবর্তে করা হত তবে বিভাগগুলি এখনও আগ্রহের সাথে আনতে পারে Set?
স্টিফেন

FETCHকোনও জেপিকিউএল স্টেটমেন্টে কীওয়ার্ডটি ব্যবহার করা কী আগ্রহের সাথে পুনরুদ্ধার করা সম্পত্তি বোঝায়?
স্টিফেন

15

JOIN

JOINকোনও সত্তা সমিতিগুলির বিরুদ্ধে ব্যবহার করার সময় , জেপিএ উত্পন্ন এসকিউএল বিবৃতিতে পিতামত্তা সত্তা এবং শিশু সত্তা সারণীর মধ্যে একটি জয়ন তৈরি করবে।

সুতরাং, এই জেপিকিউএল কোয়েরি কার্যকর করার সময় আপনার উদাহরণটি গ্রহণ করে:

FROM Employee emp
JOIN emp.department dep

হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি উত্পন্ন করতে যাচ্ছে:

SELECT emp.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id

নোট করুন যে এসকিউএল SELECTক্লজে কেবল employeeটেবিল কলাম রয়েছে, এবং এটি নেই departmentdepartmentটেবিলের কলামগুলি আনতে আমাদের JOIN FETCHপরিবর্তে ব্যবহার করা দরকার JOIN

ফেচ যোগ দিন

সুতরাং, এর সাথে তুলনা করলে JOIN, JOIN FETCHঅনুমতি দেওয়া আপনাকে SELECTউত্পন্ন এসকিউএল স্টেটমেন্টের ধারাটিতে যোগদানের টেবিল কলামগুলি প্রজেক্ট করতে দেয় ।

সুতরাং, আপনার উদাহরণে, এই জেপিকিউএল কোয়েরি কার্যকর করার সময়:

FROM Employee emp
JOIN FETCH emp.department dep

হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি উত্পন্ন করতে যাচ্ছে:

SELECT emp.*, dept.*
FROM employee emp
JOIN department dep ON emp.department_id = dep.id

দ্রষ্টব্য, এবার, departmentসারণী কলামগুলি পাশাপাশি নির্বাচন করা হয়েছে, কেবল FROMজেপিকিউএল ধারাটিতে তালিকাভুক্ত সত্তার সাথে সম্পর্কিত নয় ।

এছাড়াও, হাইবারনেট ব্যবহার JOIN FETCHকরার LazyInitializationExceptionসময় সম্বোধনের এক দুর্দান্ত উপায় হ'ল আপনি আনছেন FetchType.LAZYএমন প্রধান সত্তার পাশাপাশি আনয়ন কৌশলটি ব্যবহার করে সত্তা সমিতিগুলি সূচনা করতে পারেন ।


একই ক্যোয়ারিতে একাধিক জয়েন ফেচ ব্যবহার করা কি সম্ভব?
.আনুর canzcan

2
আপনি একাধিক বহু-এক এবং এক-থেকে-এক সমিতি এবং সর্বাধিক এক সংকলনে ফেচ যোগদান করতে পারেন। একাধিক সংগ্রহ আনা হচ্ছে, মত একের সাথে অধিকের অথবা যেগুলোর প্রচুর সাথে অধিকের সমিতির একটি শেষ হবে কার্টিজিয়ান পণ্য । তবে আপনি যদি একাধিক সংগ্রহ আনতে চান তবে আপনি দ্বিতীয়, তৃতীয়, ..., নবম সংগ্রহের জন্য গৌণ প্রশ্নগুলি ব্যবহার করতে পারেন। পরীক্ষা করে দেখুন এই নিবন্ধটি আরো বিস্তারিত জানার জন্য।
ভ্লাদ মিহলসিয়া

5

আপনি যদি @oneToOneম্যাপিং সেট করে রেখেছেন FetchType.LAZYএবং আপনি দ্বিতীয় ক্যোয়ারী ব্যবহার করেন (কারণ আপনাকে হাইপারনেট কী করবে ডিপার্টমেন্ট অবজেক্টগুলি কর্মচারী বস্তুর অংশ হিসাবে লোড করা প্রয়োজন), এটি ডিবি থেকে প্রাপ্ত প্রতিটি পৃথক কর্মচারী বস্তুর জন্য বিভাগের অবজেক্টগুলি আনার জন্য প্রশ্ন জারি করবে।

পরে, কোডটিতে আপনি কর্মচারীর মাধ্যমে বিভাগের একক-মূল্যবান সংস্থার মাধ্যমে বিভাগের অবজেক্টগুলিতে অ্যাক্সেস করতে পারেন এবং হাইবারনেট প্রদত্ত কর্মচারীর জন্য বিভাগের অবজেক্ট আনতে কোনও জিজ্ঞাসা জারি করবে না।

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


2

ধেরিক: আপনি কী বলবেন সে সম্পর্কে আমি নিশ্চিত নই, যখন আপনি আনতে ব্যবহার করবেন না তখন ফলাফলটি ধরণের হবে: List<Object[ ]>যার অর্থ অবজেক্ট টেবিলগুলির তালিকা এবং কর্মচারীর একটি তালিকা নয়।

Object[0] refers an Employee entity 
Object[1] refers a Departement entity 

যখন আপনি আনয়ন ব্যবহার করেন, কেবলমাত্র একটি নির্বাচন হয় এবং ফলাফলটি কর্মচারীর List<Employee>তালিকা থেকে বিযুক্তির তালিকা থাকে। এটি সত্তার অলস ঘোষণাকে ওভাররাইড করে।


আমি জানি না আমি আপনার উদ্বেগ বুঝতে পেরেছি কিনা। আপনি যদি ব্যবহার না করেন তবে fetchআপনার ক্যোয়ারী কেবলমাত্র কর্মচারীদেরই ফিরিয়ে দেবে। যদি বিভাগগুলি, এমনকি এক্ষেত্রেও ফেরত দেওয়া অবিরত থাকে, কারণ আপনার কর্মচারী এবং বিভাগের মধ্যে একটি ম্যাপিং (একটি @OneToMany) ফেচটাইপ.এগ্রের সাথে সেট করা আছে। এই ক্ষেত্রে, যে কোনও এইচকিউএল (সাথে fetchবা নেই) কোয়েরিটি FROM Employeeসমস্ত বিভাগ নিয়ে আসবে।
ধেরিক

আনয়ন (কেবলমাত্র শব্দ যোগ দিতে) ব্যবহার না করে ফলাফলটি সংগ্রহের একটি অ্যারে, দুটি সারি হবে, প্রথমটি কর্মচারীর সংগ্রহ এবং দ্বিতীয়টি বিভাগগুলির সংকলন। উত্সাহী আনা বা অলস আনয়ন ব্যবহার করে বিভাগগুলি আনা হবে।
বিলাল বিবিবি

এইচকিউএল আনয়ন ছাড়া এটি কেবল তখনই ঘটবে যখন কর্মচারী এবং বিভাগের মধ্যে আপনার ম্যাপিং ইগ্রার ( @OneToMany(fetch = FetchType.EAGER) হয়। যদি এটি না হয় তবে বিভাগগুলি ফেরত দেওয়া হবে না।
ধেরিক 9:15

@ দেরিক নিজে চেষ্টা করে দেখুন, আপনি ক্লাসকাস্টএক্সসেপশন পাবেন।
বিলাল বিবিবি

আমি সমস্যাটি বুঝতে পারি। আনার সমস্যা নয়, তবে কীভাবে selectএইচকিউএল তৈরি করা হয়েছিল। ব্যবহার করে দেখুন SELECT emp FROM Employee emp JOIN FETCH emp.department dep। JPA / হাইবারনেট রিটার্ন একটি এর এই আচরণ আছে Listএর Object[]যখন আপনি ommit SELECTঅংশ।
ধেরিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.