JPA (Java Persistence API) এর Criteria API একটি শক্তিশালী এবং টাইপ সেফ API যা ডাইনামিক এবং জেনেরিক SQL কোয়েরি তৈরির জন্য ব্যবহৃত হয়। Criteria API সাধারণত JPQL (Java Persistence Query Language) কোয়েরি লেখার তুলনায় অধিক শক্তিশালী এবং নিরাপদ, কারণ এটি টাইপ সেফ এবং ডাইনামিক কোয়েরি নির্মাণের সুবিধা প্রদান করে। এটি মূলত ডেটাবেস অপারেশনগুলির জন্য একাধিক ক্রাইটেরিয়া বা শর্ত ব্যবহার করে কোয়েরি লেখার সময় ব্যবহৃত হয়।
Criteria API এর সুবিধা
- টাইপ সেফ কোয়েরি: Criteria API আপনাকে ডাইনামিক কোয়েরি লেখার সময় টাইপ সেফটি নিশ্চিত করতে সহায়তা করে, অর্থাৎ, আপনি যখন কোয়েরি লিখবেন তখন সঠিক ডেটা টাইপ ব্যবহার করার কারণে কম্পাইল টাইমে ত্রুটি ধরা যাবে।
- ডাইনামিক কোয়েরি: Criteria API ব্যবহার করে আপনি কোয়েরি গঠন করার সময় শর্ত (conditions) যোগ বা বাদ দিতে পারেন, যা কোডের ফ্লেক্সিবিলিটি বৃদ্ধি করে।
- অবজেক্ট-অরিয়েন্টেড কোয়েরি লেখার সুবিধা: Criteria API অবজেক্ট-অরিয়েন্টেড স্টাইলে কোয়েরি লেখার সুবিধা দেয়, যা কোডের রিডেবিলিটি এবং বজায় রাখার ক্ষমতা বৃদ্ধি করে।
- অর্থনৈতিক এবং উন্নত পারফরম্যান্স: Criteria API জেনেরিক এবং কমপাইল টাইমে চেক হওয়ায় এর পারফরম্যান্স অনেক ক্ষেত্রে JPQL-এর তুলনায় ভালো হতে পারে।
Criteria API এর মূল উপাদান
Criteria API ব্যবহারের জন্য চারটি মূল কম্পোনেন্ট থাকে:
- CriteriaBuilder: Criteria API তৈরি করতে এটি ব্যবহার করা হয়, যা কোয়েরি তৈরির জন্য প্রাথমিকভাবে ব্যবহৃত হয়।
- CriteriaQuery: এটি একটি কোয়েরির অবজেক্ট যা CriteriaBuilder দ্বারা তৈরি করা হয়। এটি কোয়েরি গঠন এবং সেট করা হয়।
- Root: এটি একটি Entity বা টেবিলের মূল (root) অবজেক্ট, যা কোয়েরিতে ব্যবহৃত হয়।
- Predicate: এটি শর্ত বা ক্রাইটেরিয়া নির্ধারণ করতে ব্যবহৃত হয়।
Criteria API ব্যবহার করার উদাহরণ
ধরা যাক, আমাদের একটি Person Entity আছে, এবং আমরা Criteria API ব্যবহার করে কোয়েরি করতে চাই।
Person Entity Class
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private Long id;
private String name;
private int age;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Criteria API দিয়ে কোয়েরি তৈরি করা
ধরা যাক, আমাদের Person Entity থেকে কিছু নির্দিষ্ট শর্তে (যেমন age > 25) ডেটা ফেচ করতে হবে। Criteria API ব্যবহার করে আমরা এই কাজটি করব।
Criteria API উদাহরণ:
import javax.persistence.*;
import javax.persistence.criteria.*;
import java.util.List;
public class CriteriaAPIExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// CriteriaBuilder তৈরি করা
CriteriaBuilder cb = em.getCriteriaBuilder();
// CriteriaQuery তৈরি করা
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Root Entity (Person) নির্ধারণ করা
Root<Person> personRoot = cq.from(Person.class);
// শর্ত বা Predicate তৈরি করা
Predicate agePredicate = cb.gt(personRoot.get("age"), 25); // age > 25
// কোয়েরি সেট করা
cq.select(personRoot).where(agePredicate);
// কোয়েরি এক্সিকিউট করা
TypedQuery<Person> query = em.createQuery(cq);
List<Person> resultList = query.getResultList();
// রেজাল্ট প্রদর্শন
for (Person person : resultList) {
System.out.println(person.getName() + ", Age: " + person.getAge());
}
em.close();
emf.close();
}
}
ব্যাখ্যা:
- CriteriaBuilder: এটি কোয়েরি তৈরি করার জন্য ব্যবহৃত হয় এবং এটি একটি ফ্যাক্টরি হিসেবে কাজ করে।
- CriteriaQuery: এটি একটি কোয়েরি অবজেক্ট, যেখানে আমরা কোয়েরি গঠন করি।
- Root: এটি Entity ক্লাস (এখানে
Person) এর মূল অবজেক্ট। এটি কোয়েরির জন্য ব্যবহৃত হয়। - Predicate: এটি একটি শর্ত যা কোয়েরির অংশ হিসেবে ব্যবহৃত হয়। এখানে,
cb.gt(personRoot.get("age"), 25)ব্যবহার করেage > 25শর্ত তৈরি করা হয়েছে। - TypedQuery: এটি CriteriaQuery অবজেক্টের একটি টাইপ-সেফ ইমপ্লিমেন্টেশন, যা কোয়েরি এক্সিকিউট করে।
Criteria API তে বিভিন্ন অপারেশন
Criteria API তে Create, Read, Update, Delete (CRUD) অপারেশন করা যায়। আমরা আরও বিভিন্ন ধরণের শর্ত এবং অপারেশন যুক্ত করতে পারি, যেমন:
1. Multiple Conditions:
Predicate namePredicate = cb.equal(personRoot.get("name"), "John");
Predicate agePredicate = cb.gt(personRoot.get("age"), 25);
cq.where(cb.and(namePredicate, agePredicate));
2. Ordering Results:
cq.orderBy(cb.asc(personRoot.get("name"))); // Ascending order
3. Aggregate Functions:
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
Root<Person> root = countQuery.from(Person.class);
countQuery.select(cb.count(root)); // Count the number of persons
4. Group By:
cq.groupBy(personRoot.get("age"));
Criteria API এর সুবিধা
- টাইপ সেফ: Criteria API টাইপ সেফ কোয়েরি লেখার সুবিধা দেয়, যা ভুল টাইপের ডেটা ব্যবহার করার সমস্যা থেকে মুক্তি দেয়।
- ডাইনামিক কোয়েরি: Criteria API ব্যবহার করে ডাইনামিক কোয়েরি তৈরি করা যায়। এটি ডেটার শর্ত বা ক্রাইটেরিয়া পরিবর্তন করার সময় কোড সহজ এবং আরো পরিষ্কার রাখে।
- বাড়ানো নমনীয়তা: Criteria API ডাইনামিক কোয়েরি তৈরি করার ক্ষেত্রে বেশি নমনীয় এবং শক্তিশালী, যা জটিল শর্তাবলীর জন্য উপযোগী।
- এমবেডেড কোয়েরি: Criteria API ব্যবহার করে সাবকোয়য়েরি (subqueries) এবং ইনলাইন শর্তাবলী সহ এমবেডেড কোয়েরি তৈরি করা সম্ভব।
সারাংশ
Criteria API JPA এর একটি শক্তিশালী অংশ যা টাইপ সেফ, ডাইনামিক এবং অবজেক্ট-অরিয়েন্টেড কোয়েরি লেখার সুবিধা দেয়। এটি ডেটাবেসের সাথে সম্পর্কিত শর্তাবলী এবং লজিক তৈরি করার সময় কোড রিডেবিলিটি এবং নমনীয়তা নিশ্চিত করে। JPA Criteria API-র মাধ্যমে আপনি সহজেই জটিল কোয়েরি তৈরি করতে পারেন, যেমন multiple conditions, ordering, grouping, aggregation, এবং অন্যান্য advanced filtering পদ্ধতি।
Criteria API JPA (Java Persistence API) এর একটি শক্তিশালী ফিচার যা ডাইনামিক এবং টাইপ-সেফ (type-safe) কোয়েরি তৈরি করার জন্য ব্যবহৃত হয়। এটি JPQL (Java Persistence Query Language) বা SQL এর পরিবর্তে Java কোডের মাধ্যমে ডেটাবেসে কোয়েরি তৈরি করতে সহায়তা করে। Criteria API কোডের মধ্যে ডাইনামিকভাবে কোয়েরি তৈরি করার সুবিধা প্রদান করে, যা SQL বা JPQL লেখার তুলনায় বেশি নিরাপদ, রিডেবল এবং পরিবর্তনযোগ্য।
Criteria API কী এবং কীভাবে কাজ করে?
Criteria API JPA-তে টাইপ-সেফ কোয়েরি তৈরি করার জন্য ব্যবহার করা হয়। এর মাধ্যমে আপনি Java কোডে ডেটাবেসের জন্য কোয়েরি তৈরি করতে পারেন, যা ডেটাবেস স্ট্রাকচার এবং অবজেক্ট মডেলকে যথাযথভাবে ব্যবহার করে। Criteria API জেনেরিক প্রোগ্রামিং ধারণা ব্যবহার করে এবং এতে ডেটাবেস অপারেশন সহজে করা যায়।
Criteria API কোয়েরি তৈরি করার সময় Java classes এবং JPA entities এর সাথে কাজ করা হয়, যেহেতু কোয়েরি প্রক্রিয়া Java objects এবং properties এর মাধ্যমে করা হয়। এর মাধ্যমে কোয়েরি ফিল্টার, প্যারামিটারাইজড কোয়েরি, অর্ডারিং এবং গ্রুপিং করা যায়।
Criteria API এর সুবিধা
- টাইপ-সেফ কোয়েরি: Criteria API কোয়েরি লেখার সময় টাইপ-সেফ (type-safe) হয়, অর্থাৎ কোড কম্পাইল হওয়া পর্যন্ত কোনো টাইপ বা সিনট্যাক্সের ত্রুটি থাকে না। এটি জাভা কোডের মধ্যে কোয়েরি তৈরি করতে সাহায্য করে, যেখানে টাইপ মিসম্যাচ বা ভুল কলামের নাম কম হয়।
- ডাইনামিক কোয়েরি তৈরি: Criteria API দিয়ে কোয়েরি কোডের মধ্যে ডাইনামিকভাবে তৈরি করা যায়। উদাহরণস্বরূপ, ইউজারের ইনপুট অনুযায়ী কোয়েরি ফিল্টার বা কন্ডিশন যোগ করা সম্ভব হয়।
- SQL এবং JPQL এর বিকল্প: JPQL বা SQL লেখার চাইতে Criteria API ব্যবহার করা অনেক বেশি সুবিধাজনক, কারণ এটি ডাইনামিক কোয়েরি লেখার সময় অটোমেটিক টাইপ চেকিং এবং ভুল কোড লেখার সম্ভাবনা কমিয়ে দেয়।
- ক্লিয়ার এবং রিডেবল কোড: Criteria API কোডের মাধ্যমে কোয়েরি তৈরি করা অনেক বেশি রিডেবল এবং সুনির্দিষ্ট হয়, যেহেতু কোডে ডাইনামিক অপ্রয়োজনীয় অংশ বাদ দেওয়া যায় এবং অবজেক্টের মাধ্যমে কোয়েরি তৈরি করা হয়।
- পরিবর্তনযোগ্য কোয়েরি: Criteria API এর মাধ্যমে কোয়েরি পরিবর্তন বা কাস্টমাইজ করা সহজ হয়। কারণ কোয়েরি একবার তৈরি করার পর আপনি কোয়েরিতে নতুন কন্ডিশন বা ফিল্টার যোগ করতে পারেন, যা JPQL বা SQL এর মাধ্যমে করার তুলনায় অনেক সহজ।
Criteria API দিয়ে কোয়েরি লেখার উদাহরণ
ডেটাবেস টেবিল: Person
ধরা যাক, আমাদের একটি Person Entity ক্লাস আছে যার ফিল্ডগুলো হলো id, name, এবং age।
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private Long id;
private String name;
private int age;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Criteria API কোয়েরি উদাহরণ
Criteria API ব্যবহার করে Person টেবিল থেকে age 25 এর বেশি এমন সব Person রেকর্ড খুঁজে বের করা:
import javax.persistence.*;
import javax.persistence.criteria.*;
public class CriteriaAPIExample {
public static void main(String[] args) {
// EntityManagerFactory তৈরি করা
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// CriteriaBuilder তৈরি করা
CriteriaBuilder cb = em.getCriteriaBuilder();
// CriteriaQuery তৈরি করা
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Root (From clause) তৈরি করা
Root<Person> personRoot = cq.from(Person.class);
// Where clause - age > 25
Predicate agePredicate = cb.gt(personRoot.get("age"), 25);
cq.where(agePredicate);
// Query execution
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Results প্রদর্শন করা
for (Person person : results) {
System.out.println("Person Name: " + person.getName() + ", Age: " + person.getAge());
}
em.close();
emf.close();
}
}
Explanation:
- CriteriaBuilder: এটি Criteria API এর মাধ্যমে কোয়েরি তৈরি করার জন্য ব্যবহৃত হয়।
- Root personRoot: এটি FROM ক্লজের জন্য ব্যবহৃত হয় যা ডেটাবেস টেবিলের ভিত্তি হিসেবে কাজ করে।
- Predicate agePredicate: এটি WHERE ক্লজে একটি শর্ত নির্ধারণ করে, যেমন
age > 25। - CriteriaQuery: এটি কোয়েরি তৈরি করে এবং তারপর TypedQuery এর মাধ্যমে সেটি চালানো হয়।
Criteria API তে আরও কিছু অপশন:
Order By: Criteria API ব্যবহার করে অর্ডারিং করা যায়:
cq.orderBy(cb.asc(personRoot.get("name"))); // Name এর অক্ষরের উপর Ascending অর্ডারProjection (Select specific fields): আপনি একটি নির্দিষ্ট ফিল্ডের মানও পেতে পারেন:
cq.select(personRoot.get("name"));Group By: Criteria API এর মাধ্যমে গ্রুপিং করা সম্ভব:
cq.groupBy(personRoot.get("age"));
Criteria API কেন প্রয়োজন?
- ডাইনামিক কোয়েরি নির্মাণ: Criteria API কোয়েরি ডাইনামিকভাবে তৈরি করতে সাহায্য করে, যা SQL বা JPQL এর মাধ্যমে সম্ভব নয়। এটি সেই ক্ষেত্রে কার্যকর যেখানে ইউজার ইনপুটের উপর ভিত্তি করে কোয়েরি তৈরি করতে হয়।
- টাইপ-সেফ কোয়েরি: Criteria API ব্যবহার করে কোডে টাইপ মিসম্যাচ বা ভুল কলাম নাম লেখার সম্ভাবনা কমে যায়, কারণ এটি Java objects এর মাধ্যমে কাজ করে।
- কমপ্লেক্স কোয়েরি সমাধান: JPA Criteria API জটিল কোয়েরি গঠন করতে সহায়তা করে, যেমন কন্ডিশন, অর্ডার, গ্রুপিং ইত্যাদি যোগ করা সহজ হয়।
- JPA ও ডেটাবেস ইন্টিগ্রেশন: Criteria API JPA এর সাথে ইন্টিগ্রেশন সহজ করে এবং এটি ডেটাবেস সিস্টেমের জন্য স্বাধীন। এটি SQL ডায়ালেক্টের উপর নির্ভর করে না।
সারাংশ
Criteria API JPA এর একটি শক্তিশালী ফিচার যা ডাইনামিক, টাইপ-সেফ এবং জটিল কোয়েরি তৈরি করার সুবিধা প্রদান করে। এটি SQL বা JPQL এর তুলনায় বেশি নিরাপদ এবং পড়তে সহজ কোড তৈরি করতে সাহায্য করে। Criteria API দিয়ে কোয়েরি লেখার সময় ডেটাবেস টেবিল এবং Java অবজেক্টের মধ্যে সম্পর্ক এবং শর্তাবলী নির্ধারণ করা সহজ হয়, যা ডেভেলপমেন্ট প্রক্রিয়াকে আরো কার্যকরী এবং দ্রুত করে তোলে।
JPA (Java Persistence API) এর Criteria API ডেভেলপারদের জন্য একটি টাইপ-সেফ, প্ল্যাটফর্ম-নিরপেক্ষ উপায় প্রদান করে, যার মাধ্যমে JPQL (Java Persistence Query Language) ব্যবহার না করে ডাইনামিকভাবে ডেটাবেস কুয়েরি তৈরি করা যায়। CriteriaQuery, CriteriaBuilder, এবং Root ক্লাসগুলি Criteria API এর একটি গুরুত্বপূর্ণ অংশ।
এই ক্লাসগুলির সাহায্যে ডেটাবেস কুয়েরি তৈরি এবং এক্সিকিউট করা যায় যা আরও টাইপ-সেফ, এবং কোডে এক্সপ্রেশন অ্যানালাইসিসের মাধ্যমে ডাইনামিক কোয়েরি তৈরি করতে সহায়তা করে।
১. CriteriaBuilder ক্লাস
CriteriaBuilder ক্লাসটি CriteriaQuery তৈরি করার জন্য ব্যবহৃত হয় এবং JPA কুয়েরি শর্তাবলী (conditions) তৈরি করার জন্য একটি সাধারণ API প্রদান করে।
- CriteriaBuilder ক্লাসে criteria(), equal(), like(), greaterThan(), lessThan() ইত্যাদি মেথড রয়েছে, যা ব্যবহার করে আপনি কুয়েরি তৈরির শর্তাবলী (conditions) সংজ্ঞায়িত করতে পারেন।
CriteriaBuilder উদাহরণ:
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;
public class CriteriaBuilderExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpaUnit");
EntityManager em = emf.createEntityManager();
// Create CriteriaBuilder instance
CriteriaBuilder cb = em.getCriteriaBuilder();
// Create CriteriaQuery instance
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Define the root (the entity class)
Root<Person> root = cq.from(Person.class);
// Define the condition (where clause)
cq.select(root).where(cb.equal(root.get("age"), 30));
// Execute the query
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Output the results
for (Person person : results) {
System.out.println(person.getName() + " - " + person.getAge());
}
em.close();
emf.close();
}
}
Explanation:
- CriteriaBuilder:
em.getCriteriaBuilder()ব্যবহার করে CriteriaBuilder ইনস্ট্যান্স তৈরি করা হয়। - Root:
Root<Person> root = cq.from(Person.class);এখানেPersonEntity ক্লাসের রুট ডিফাইন করা হচ্ছে। - CriteriaQuery: CriteriaQuery ব্যবহার করে একটি কুয়েরি তৈরি করা হয় যেখানে
select(root)এর মাধ্যমে রিটার্ন করার জন্য Person অবজেক্ট নির্বাচন করা হয়। - where():
cb.equal(root.get("age"), 30)শর্তের মাধ্যমেage৩০ এর সমান এমন সব ব্যক্তি পাওয়া যাবে।
২. CriteriaQuery ক্লাস
CriteriaQuery ক্লাস Criteria API তে কুয়েরি তৈরি এবং পরিচালনা করার জন্য ব্যবহৃত হয়। এটি মূলত SELECT কুয়েরি তৈরি করার জন্য ব্যবহৃত হয় এবং এতে ডাইনামিক কুয়েরি তৈরি করার জন্য শর্তাবলী সংজ্ঞায়িত করা হয়।
CriteriaQuery উদাহরণ:
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;
public class CriteriaQueryExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpaUnit");
EntityManager em = emf.createEntityManager();
// Create CriteriaQuery instance
CriteriaQuery<Person> cq = em.getCriteriaBuilder().createQuery(Person.class);
// Define the root (the entity class)
Root<Person> root = cq.from(Person.class);
// Define the select part (selecting all persons)
cq.select(root);
// Execute the query
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Output the results
for (Person person : results) {
System.out.println(person.getName() + " - " + person.getAge());
}
em.close();
emf.close();
}
}
Explanation:
- CriteriaQuery:
CriteriaQuery<Person> cq = em.getCriteriaBuilder().createQuery(Person.class);এটি CriteriaQuery এর ইনস্ট্যান্স তৈরি করছে যা Person Entity ক্লাসের জন্য। - Root:
Root<Person> root = cq.from(Person.class);এই অংশে Person ক্লাস থেকে রুট অবজেক্ট তৈরি করা হচ্ছে। - select(): কুয়েরির মাধ্যমে
cq.select(root)সকল Person অবজেক্ট নির্বাচন করা হচ্ছে।
৩. Root ক্লাস
Root ক্লাস JPA Criteria API-তে একটি Entity ক্লাসের সাথে সম্পর্কিত রুট অবজেক্ট প্রতিনিধিত্ব করে। এটি ডেটাবেস টেবিলের জন্য FROM ক্লজের মতো কাজ করে এবং Entity ক্লাসের প্রপার্টি অ্যাক্সেস করার জন্য ব্যবহার করা হয়।
Root উদাহরণ:
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;
public class RootExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpaUnit");
EntityManager em = emf.createEntityManager();
// Create CriteriaBuilder and CriteriaQuery instances
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Define the root (the entity class)
Root<Person> root = cq.from(Person.class);
// Select all persons
cq.select(root);
// Execute the query
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Output the results
for (Person person : results) {
System.out.println(person.getName() + " - " + person.getAge());
}
em.close();
emf.close();
}
}
Explanation:
- Root:
Root<Person> root = cq.from(Person.class);এখানে Person Entity ক্লাসের রুট অবজেক্ট তৈরি করা হচ্ছে, যা Criteria API তেFROMক্লজের কাজ করে। - cq.select(root): এখানে select মেথডের মাধ্যমে Person টেবিলের সব রেকর্ড সিলেক্ট করা হয়েছে।
৪. Criteria API ব্যবহার করে ডাইনামিক কুয়েরি তৈরি
JPA Criteria API দিয়ে আপনি ডাইনামিক কুয়েরি তৈরি করতে পারেন, যেমন WHERE, ORDER BY, এবং JOIN শর্তগুলি যোগ করা। এতে SQL কুয়েরি লেখা ছাড়াই ডেটাবেস কুয়েরি তৈরি করা সম্ভব।
ডাইনামিক WHERE শর্ত (Dynamic WHERE Clause Example)
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;
public class DynamicWhereClauseExample {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpaUnit");
EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
// Dynamic condition: Where age > 30
Predicate agePredicate = cb.greaterThan(root.get("age"), 30);
cq.where(agePredicate);
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Output the results
for (Person person : results) {
System.out.println(person.getName() + " - " + person.getAge());
}
em.close();
emf.close();
}
}
Explanation:
- Predicate:
cb.greaterThan(root.get("age"), 30)এখানে age প্রপার্টির জন্য একটি শর্ত তৈরি করা হয়েছে, যা কেবল age > 30 কন্ডিশন প্রাপ্ত রেকর্ডগুলো সিলেক্ট করবে।
সারাংশ
JPA Criteria API একটি শক্তিশালী টুল যা CriteriaQuery, CriteriaBuilder, এবং Root ক্লাসের মাধ্যমে ডাইনামিক এবং টাইপ-সেফ SQL কুয়েরি তৈরি করতে সাহায্য করে। এই API ব্যবহার করে আপনি ডেটাবেস কুয়েরি তৈরি করতে পারেন যা SQL কুয়েরির তুলনায় আরও নিরাপদ এবং প্ল্যাটফর্ম নিরপেক্ষ হয়। CriteriaBuilder ব্যবহার করে কুয়েরির শর্ত তৈরি, Root ব্যবহার করে Entity ক্লাসের প্রপার্টি অ্যাক্সেস এবং CriteriaQuery ব্যবহার করে ডাইনামিক কুয়েরি তৈরি করা হয়, যা JPA ডেটাবেস অপারেশনকে আরও কার্যকরী এবং নমনীয় করে তোলে।
JPA Criteria API হলো একটি শক্তিশালী ফিচার যা ডাইনামিক কুয়েরি তৈরি করতে সাহায্য করে। SQL বা JPQL কোডের মতো স্ট্রিং ব্যবহার না করে Criteria API ব্যবহার করে কুয়েরি তৈরি করা হয়। এটি ট্যাইপ সেফ, ডাইনামিক এবং আরও ফ্লেক্সিবল কুয়েরি লেখার জন্য ব্যবহৃত হয়।
Criteria API এর সাহায্যে আপনি ডাইনামিক কুয়েরি তৈরি করতে পারেন যেগুলি runtime এ তৈরি হয়, যা SQL বা JPQL কুয়েরির তুলনায় আরো ভালো।
Criteria API এর সুবিধা
- Type-safe: কোড লেখার সময় আপনি অটো কমপ্লিশন, টাইপ চেকিং এবং ইরর হ্যান্ডলিং এর সুবিধা পাবেন।
- Dynamic Queries: runtime এ কুয়েরি তৈরি এবং ইভ্যালুয়েট করা সম্ভব।
- Reuse: একাধিক কুয়েরি তৈরি এবং পুনঃব্যবহার করা সহজ।
- Maintainability: কোড আরও পরিষ্কার এবং বজায় রাখা সহজ হয়, বিশেষ করে জটিল কুয়েরি লেখার সময়।
১. Criteria API Setup:
Criteria API ব্যবহার করার জন্য CriteriaBuilder, CriteriaQuery, এবং Root ক্লাসগুলো ব্যবহার করা হয়।
Criteria API এর মৌলিক স্টেপস:
- CriteriaBuilder: এটি Criteria API এর মাধ্যমে কুয়েরি তৈরি করতে ব্যবহৃত হয়।
- CriteriaQuery: এটি কুয়েরি কাঠামো ধারণ করে।
- Root: এটি Entity ক্লাসের জন্য root অবজেক্ট তৈরি করে।
২. Criteria API Example: Basic Query
ধরা যাক আমাদের একটি Person Entity রয়েছে এবং আমরা Criteria API ব্যবহার করে ডাইনামিক কুয়েরি তৈরি করতে চাই। এখানে আমরা একটি সহজ উদাহরণ দেখাবো যেখানে Person Entity তে নির্দিষ্ট বয়সের বেশি ব্যবহারকারীদের নাম এবং বয়স রিট্রিভ করা হবে।
Person Entity Class:
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private Long id;
private String name;
private int age;
// Getters and Setters
}
Criteria API Example - Basic Query:
import javax.persistence.*;
import javax.persistence.criteria.*;
import java.util.List;
public class CriteriaApiExample {
public static void main(String[] args) {
// Create EntityManagerFactory and EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// Start the transaction
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Root of the query (person table)
Root<Person> personRoot = cq.from(Person.class);
// Select from Person where age > 30
cq.select(personRoot).where(cb.greaterThan(personRoot.get("age"), 30));
// Execute the query and get results
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Display results
for (Person person : results) {
System.out.println("Name: " + person.getName() + ", Age: " + person.getAge());
}
// Close EntityManager and EntityManagerFactory
em.close();
emf.close();
}
}
Explanation:
- CriteriaBuilder:
cbহলো CriteriaBuilder অবজেক্ট, যা কুয়েরি তৈরি করতে ব্যবহৃত হয়। - CriteriaQuery:
cqহলো CriteriaQuery অবজেক্ট যা কুয়েরির কাঠামো ধারণ করে। - Root:
personRootহলোPersonEntity এর জন্য root অবজেক্ট। - Predicate:
cb.greaterThan()ব্যবহার করে বয়স ৩০ এর বেশি এমন রেকর্ড বের করা হয়।
৩. Dynamic Queries with Criteria API
এখন, আমরা দেখব কিভাবে Criteria API ব্যবহার করে ডাইনামিক কুয়েরি তৈরি করা যায়। এটি ডাইনামিকভাবে কুয়েরি শর্ত (conditions) যোগ করার জন্য উপযুক্ত।
Dynamic Criteria API Example:
ধরা যাক, আমরা একটি ডাইনামিক কুয়েরি তৈরি করতে চাই যেখানে ব্যবহারকারীর নাম এবং বয়স ফিল্টার করা যাবে, এবং এই ফিল্টারগুলো runtime এ নির্ধারণ করা হবে।
import javax.persistence.*;
import javax.persistence.criteria.*;
import java.util.List;
public class DynamicCriteriaExample {
public static void main(String[] args) {
// Create EntityManagerFactory and EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// Start the transaction
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
// Root of the query (person table)
Root<Person> personRoot = cq.from(Person.class);
// Build dynamic conditions
Predicate finalPredicate = cb.conjunction(); // Start with a true condition (AND)
// Example dynamic condition 1: Filter by age (if condition is met)
Integer minAge = 30;
if (minAge != null) {
finalPredicate = cb.and(finalPredicate, cb.greaterThan(personRoot.get("age"), minAge));
}
// Example dynamic condition 2: Filter by name (if condition is met)
String namePattern = "John";
if (namePattern != null && !namePattern.isEmpty()) {
finalPredicate = cb.and(finalPredicate, cb.like(personRoot.get("name"), "%" + namePattern + "%"));
}
// Apply conditions to the query
cq.where(finalPredicate);
// Execute the query and get results
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
// Display results
for (Person person : results) {
System.out.println("Name: " + person.getName() + ", Age: " + person.getAge());
}
// Close EntityManager and EntityManagerFactory
em.close();
emf.close();
}
}
Explanation:
- Dynamic Predicate: এখানে
cb.conjunction()ব্যবহার করা হয়েছে, যা প্রথমে একটি TRUE শর্ত তৈরি করে এবং পরে ডাইনামিকভাবে অন্যান্য শর্ত যোগ করা হয়। - Dynamic Filtering: আমরা age এবং name এর উপর ডাইনামিক ফিল্টার যোগ করেছি, এবং শুধুমাত্র তখনই শর্তগুলি কার্যকর হয় যখন তাদের মান দেয়া থাকে।
- Predicate: এটি
ANDঅপারেটর হিসেবে কাজ করে, অর্থাৎ দুটি শর্ত একসাথে মিলিয়ে কাজ করবে।
৪. Criteria API এর অন্যান্য কার্যকরী ফিচার
Criteria API ব্যবহারের সময়, আপনি আরও অনেক কার্যকরী ফিচার ব্যবহার করতে পারেন যেমন:
- Ordering (Sorting): ডেটাকে ক্রম (ascending/descending) অনুযায়ী সাজানো।
- GroupBy: গ্রুপিং করতে পারেন নির্দিষ্ট কলামের উপর ভিত্তি করে।
- Aggregation: COUNT, SUM, AVG ইত্যাদি অগ্রিগেট ফাংশন ব্যবহার করতে পারেন।
Criteria API with Sorting (Ordering) Example:
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> personRoot = cq.from(Person.class);
// Sort by name in ascending order
cq.orderBy(cb.asc(personRoot.get("name")));
TypedQuery<Person> query = em.createQuery(cq);
List<Person> results = query.getResultList();
for (Person person : results) {
System.out.println("Name: " + person.getName());
}
Criteria API with Aggregation Example:
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Person> personRoot = cq.from(Person.class);
cq.select(cb.count(personRoot)); // Count the number of persons
TypedQuery<Long> query = em.createQuery(cq);
Long result = query.getSingleResult();
System.out.println("Total Persons: " + result);
সারাংশ
JPA Criteria API ডাইনামিক কুয়েরি তৈরি করার জন্য একটি শক্তিশালী এবং টাইপ সেফ উপায় প্রদান করে। এটি ডেভেলপারদেরকে ডাইনামিকভাবে কুয়েরি কন্ডিশন তৈরি করার সুযোগ দেয় এবং কোডিং এর সময় টাইপ চেকিং ও সঠিকতা নিশ্চিত করে।
- Criteria API ব্যবহার করে আপনি ডাইনামিক ফিল্টারিং, সটিং, গ্রুপিং এবং অগ্রিগেটিং সহজেই করতে পারেন।
- Criteria API দিয়ে JPA কুয়েরি লেখার সময় SQL বা JPQL এর সাথে তুলনামূলকভাবে কমপ্লেক্স এবং টাইপ সেফ কুয়েরি লেখা যায়।
JPA (Java Persistence API) ব্যবহার করে ডেটাবেসের সাথে কাজ করার সময় জটিল কুয়েরি তৈরি করতে JPQL (Java Persistence Query Language) বা Criteria API ব্যবহার করা যায়। JPQL, SQL এর মতো হলেও এটি অবজেক্ট ভিত্তিক এবং Entity অবজেক্টের সাথে কাজ করে। JPA এর মাধ্যমে complex queries তৈরি করা যায় যা ডেটাবেস টেবিলের মধ্যে জটিল সম্পর্ক বা শর্তের উপর ভিত্তি করে ডেটা রিট্রিভ করতে সহায়তা করে।
এই টিউটোরিয়ালে আমরা JPQL এবং Criteria API ব্যবহার করে complex queries তৈরি করার উদাহরণ দেখব।
১. JPQL (Java Persistence Query Language) ব্যবহার করে Complex Query
JPQL একটি স্ট্রিং ভিত্তিক কুয়েরি ভাষা যা Entity ক্লাসে ডেটা রিট্রিভ করার জন্য ব্যবহৃত হয়। JPQL-এর মাধ্যমে আপনি SQL-এর মতো কুয়েরি করতে পারবেন, কিন্তু এটি টেবিলের পরিবর্তে Entity ক্লাসের ওপর কাজ করে।
1.1 JPQL Query Example
ধরা যাক, আমাদের একটি Employee Entity রয়েছে যা name, age, salary, এবং department ফিল্ডগুলো ধারণ করে। এখন আমরা একটি জটিল কুয়েরি তৈরি করব যা:
- নির্দিষ্ট বয়সের বেশি কর্মচারীদের তথ্য রিটার্ন করবে।
- শুধুমাত্র নির্দিষ্ট department থেকে কর্মচারীদের তথ্য রিটার্ন করবে।
Entity Class: Employee
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Employee {
@Id
private Long id;
private String name;
private int age;
private double salary;
private String department;
// Getters and Setters
}
JPQL Query Example:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.List;
public class JpaComplexQueryExample {
public static void main(String[] args) {
// Create EntityManagerFactory and EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// Create a JPQL query to retrieve employees with age > 30 and from "IT" department
String jpql = "SELECT e FROM Employee e WHERE e.age > :age AND e.department = :dept";
Query query = em.createQuery(jpql);
// Set the parameters for the query
query.setParameter("age", 30);
query.setParameter("dept", "IT");
// Execute the query and get the result
List<Employee> employees = query.getResultList();
// Print the results
for (Employee employee : employees) {
System.out.println("Employee: " + employee.getName() + ", Age: " + employee.getAge() + ", Department: " + employee.getDepartment());
}
// Close EntityManager and EntityManagerFactory
em.close();
emf.close();
}
}
Explanation:
- JPQL Query:
SELECT e FROM Employee e WHERE e.age > :age AND e.department = :dept- এটি একটি সিম্পল SELECT কুয়েরি যাageএবংdepartmentএর ভিত্তিতে কর্মচারীদের তথ্য রিটার্ন করবে। query.setParameter(): এটি কুয়েরির প্যারামিটার নির্ধারণ করে। এখানেageএবংdeptপ্যারামিটার ব্যবহার করা হয়েছে।
২. Criteria API ব্যবহার করে Complex Query
Criteria API JPA-এর একটি শক্তিশালী ফিচার যা টাইপ সেফ কুয়েরি তৈরি করতে সহায়তা করে। এটি ডায়নামিক কুয়েরি তৈরি করার জন্য ব্যবহৃত হয় এবং Java কোডের মাধ্যমে কুয়েরি তৈরি করা সম্ভব হয়।
2.1 Criteria API Query Example
ধরা যাক, আমরা Criteria API ব্যবহার করে একই কুয়েরি তৈরি করতে চাই, যেখানে age এবং department এর ভিত্তিতে কর্মচারীদের তথ্য রিট্রিভ করা হবে।
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
public class JpaCriteriaApiExample {
public static void main(String[] args) {
// Create EntityManagerFactory and EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// Create CriteriaBuilder and CriteriaQuery
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
// Define the root of the query (Entity to be queried)
Root<Employee> employeeRoot = cq.from(Employee.class);
// Define the conditions (age > 30 AND department = "IT")
Predicate agePredicate = cb.greaterThan(employeeRoot.get("age"), 30);
Predicate departmentPredicate = cb.equal(employeeRoot.get("department"), "IT");
// Combine the conditions using AND
cq.select(employeeRoot).where(cb.and(agePredicate, departmentPredicate));
// Execute the query and get the result
List<Employee> employees = em.createQuery(cq).getResultList();
// Print the results
for (Employee employee : employees) {
System.out.println("Employee: " + employee.getName() + ", Age: " + employee.getAge() + ", Department: " + employee.getDepartment());
}
// Close EntityManager and EntityManagerFactory
em.close();
emf.close();
}
}
Explanation:
- CriteriaBuilder:
CriteriaBuilderJPA এর কুয়েরি তৈরি করার জন্য ব্যবহৃত হয়। - Root:
Root<Employee>Entity থেকে ডেটা রিট্রিভ করার জন্য একটি রুট অবজেক্ট তৈরি করা হয়। - Predicate:
Predicateক্লাসটি শর্ত তৈরি করার জন্য ব্যবহৃত হয়। cb.greaterThan()এবংcb.equal(): এগুলো শর্ত তৈরি করার জন্য ব্যবহৃত হয়, যেখানে বয়স বড় (greaterThan) এবং বিভাগ সমান (equal) হতে হবে।cb.and(): এই পদ্ধতিটি দুটি শর্ত একসাথে যুক্ত করে।
৩. প্যারামিটারাইজড JPQL কুয়েরি
JPQL কুয়েরি আরও প্যারামিটারাইজড হতে পারে, যেখানে ডাইনামিক প্যারামিটার ব্যবহার করা হয়। এটি খুবই কার্যকরী যখন ব্যবহারকারী ইনপুট বা কন্ডিশনের উপর ভিত্তি করে কুয়েরি তৈরি করতে হয়।
JPQL Example with Dynamic Parameters
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.List;
public class DynamicJPQLExample {
public static void main(String[] args) {
// Create EntityManagerFactory and EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPAUnit");
EntityManager em = emf.createEntityManager();
// Create a dynamic JPQL query
String jpql = "SELECT e FROM Employee e WHERE e.salary > :minSalary AND e.age < :maxAge";
Query query = em.createQuery(jpql);
// Set dynamic parameters
query.setParameter("minSalary", 50000);
query.setParameter("maxAge", 50);
// Execute the query and get the result
List<Employee> employees = query.getResultList();
// Print the results
for (Employee employee : employees) {
System.out.println("Employee: " + employee.getName() + ", Salary: " + employee.getSalary() + ", Age: " + employee.getAge());
}
// Close EntityManager and EntityManagerFactory
em.close();
emf.close();
}
}
Explanation:
setParameter(): এই পদ্ধতিটি ডাইনামিক প্যারামিটার ব্যবহার করার জন্য ব্যবহৃত হয়। এখানে minSalary এবং maxAge প্যারামিটার ব্যবহার করা হয়েছে।
সারাংশ
JPA ব্যবহার করে complex queries তৈরি করতে JPQL (Java Persistence Query Language) এবং Criteria API দুটি শক্তিশালী অপশন। JPQL SQL-এর মতো কুয়েরি লেখার সুবিধা দেয়, যেখানে Criteria API টাইপ সেফ এবং ডাইনামিক কুয়েরি তৈরি করার জন্য ব্যবহার করা হয়।
- JPQL-এ parameterized queries এবং dynamic conditions সহজে তৈরি করা যায়।
- Criteria API জটিল কুয়েরি তৈরি করতে আরও বেশি নমনীয় এবং টাইপ সেফ পদ্ধতি প্রদান করে।
এই পদ্ধতিগুলি JPA-এর শক্তি বাড়ায় এবং ডেটাবেস থেকে ডেটা রিট্রিভ করতে ডেভেলপারদের আরও সহজ এবং কার্যকরী উপায় প্রদান করে।
Read more