আপনি কীভাবে এইচকিউএলে একটি পৃথক কোয়েরি তৈরি করবেন


100

এইচকিউএলে একটি পৃথক কোয়েরি তৈরি করার কোনও উপায় আছে কি? হয় "স্বতন্ত্র" কীওয়ার্ড বা অন্য কোনও পদ্ধতি ব্যবহার করে। আমি নিশ্চিত নই যে স্বতন্ত্রটি এইচকিউএলের জন্য একটি বৈধ কী-ওয়ার্ক কিনা, তবে আমি এসকিউএল কীওয়ার্ড "স্বতন্ত্র" কীওয়ার্ডের এইচকিউএল সমতুল্য সন্ধান করছি।

উত্তর:


124

এখানে আমরা ব্যবহার করি এমন এইচকিএল-এর একটি স্নিপেট। (পরিচয় রক্ষার জন্য নাম পরিবর্তন করা হয়েছে)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});

আমি কেবল কখনও মাইএসকিউএল দিয়ে হাইবারনেট ব্যবহার করেছি - এমএসকিউএল সমস্যাটি কীভাবে মোকাবেলা করতে হবে তা নিশ্চিত নয়।
ফুট

হাইবারনেটটিম্পলেট () ফাংশনটি হ'ল স্ট্রিং ফ্রেমওয়ার্কের সাথে সম্পর্কিত, স্ট্যান্ডার্ড এপিআইয়ের নয়। আপনি কি স্প্রিং ফ্রেমওয়ার্ক ব্যবহার না করে একটি সমতুল্য সম্পর্কে জানেন?
ম্যাথিউইউ.ভি.ভি.

57

এটি লক্ষণীয় যে distinctএইচকিউএল-এর distinctকীওয়ার্ডটি এসকিউএল- এর কীওয়ার্ডটিতে সরাসরি ম্যাপ করে না ।

আপনি যদি distinctএইচকিউএলটিতে কীওয়ার্ডটি ব্যবহার করেন তবে কখনও কখনও হাইবারনেট distinctএসকিউএল কীওয়ার্ডটি ব্যবহার করবে তবে কিছু পরিস্থিতিতে এটি পৃথক ফলাফল তৈরি করতে ফলাফল ট্রান্সফর্মার ব্যবহার করবে। উদাহরণস্বরূপ, যখন আপনি এই জাতীয় বাইরের জোড় ব্যবহার করছেন:

select distinct o from Order o left join fetch o.lineItems

এক্ষেত্রে এসকিউএল স্তরে নকলগুলি ফিল্টার করা সম্ভব নয়, সুতরাং হাইবারনেট এসকিউএল কোয়েরি ResultTransformerসম্পাদনের পরে ডুপ্লিকেটগুলি ফিল্টার করতে একটি ব্যবহার করে।



16

পরের বারের মতো কিছু করুন do

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();

4
এটি সাবঅপটিমাল: ডাটাবেস স্তরে পুনরাবৃত্তিগুলি বাদ দেওয়ার পরিবর্তে এটি ডাটাবেস থেকে পুনরাবৃত্তি এবং সমস্তগুলির সাথে মেমরিটিতে ডেটা টানবে এবং তারপরে পুনরাবৃত্তিগুলি পরিত্যাগ করবে; ডেটা কতবার পুনরাবৃত্তি করে তার উপর নির্ভর করে, এটি I / O ক্রিয়াকলাপকে অনেক বেশি বাড়িয়ে তুলতে পারে।
হ্যারল্ডো_ওকে

9

আপনি Criteria.DISTINCT_ROOT_ENTITYহাইবারনেট এইচকিউএল কোয়েরিও ব্যবহার করতে পারেন ।

উদাহরণ:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();

4
এটি সাবঅপটিমাল: ডাটাবেস স্তরে পুনরাবৃত্তিগুলি বাদ দেওয়ার পরিবর্তে এটি ডাটাবেস থেকে পুনরাবৃত্তি এবং সমস্তগুলির সাথে মেমরিটিতে ডেটা টানবে এবং তারপরে পুনরাবৃত্তিগুলি পরিত্যাগ করবে; ডেটা কতবার পুনরাবৃত্তি করে তার উপর নির্ভর করে, এটি I / O ক্রিয়াকলাপকে অনেক বেশি বাড়িয়ে তুলতে পারে।
হ্যারল্ডো_ওকে

4

এইচকিউএল কোয়েরিগুলির সাথে মিলিত রেজাল্ট ট্রান্সফর্মারগুলিতে আমার কিছু সমস্যা ছিল। আমি যখন চেষ্টা করেছি

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

এটা কাজ করে না। আমাকে এইভাবে ম্যানুয়ালি রূপান্তর করতে হয়েছিল:

final List found = trans.transformList(qry.list());

ক্রিটারিয়া এপিআই ট্রান্সফর্মারগুলির সাথে ঠিকঠাক কাজ করেছে।


10 কে (:
টিমজ

3

আমার মূল প্রশ্নটি মডেলটিতে এটির মতো দেখাচ্ছে:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

এবং আমি এখনও "স্বতন্ত্র" ফলাফল হিসাবে বিবেচিত যা পাচ্ছিলাম না। তারা টেবিলে একটি প্রাথমিক কী সংমিশ্রণের ভিত্তিতে স্বতন্ত্র ছিল।

সুতরাং DaoImplআমি একটি লাইন পরিবর্তন যুক্ত করেছি এবং শেষ পর্যন্ত আমি চাই "স্বতন্ত্র" রিটার্ন পেয়েছি। একটি উদাহরণ হ'ল চারবার 00 বার দেখার পরিবর্তে এখন কেবল এটি একবার দেখছি। আমি এখানে কোড যুক্ত করেছি DaoImpl:

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

আমি আশা করি এটি সাহায্য করেছে! আবার, আপনি কেবল কোডিং অনুশীলনগুলি অনুসরণ করছেন যা পরিষেবা, দাও এবং প্রকল্পের মডেল ধরণের প্রয়োগ করে this


2

মনে করুন আপনি গ্রাহক সত্ত্বাকে CUSTOMER_INFORMATION টেবিলটিতে ম্যাপ করেছেন এবং আপনি গ্রাহকের স্বতন্ত্র প্রথম নামের তালিকা পেতে চান। এটি পেতে আপনি নীচের স্নিপেট ব্যবহার করতে পারেন।

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

আমি আসা করি এটা সাহায্য করবে. সুতরাং এখানে আমরা স্বতন্ত্র কীওয়ার্ড ব্যবহার না করে গ্রুপটি ব্যবহার করছি।

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


1

স্বতন্ত্র ক্ষেত্রগুলি ব্যবহার করার জন্য হাইবারনেট ক্যোয়ারী ল্যাঙ্গুয়েজের জন্য একটি উত্তর পেয়েছি। আপনি * নির্বাচন করুন থেকে নির্বাচন (TO_CITY) থেকে FLIGHT_ROUTE *। আপনি যদি এসকিউএল কোয়েরি ব্যবহার করেন তবে এটি স্ট্রিং তালিকাটি ফিরিয়ে দেয়। সত্তা শ্রেণীর দ্বারা আপনি এটির ফেরতের মানটি ব্যবহার করতে পারবেন না। সুতরাং এই ধরণের সমস্যা সমাধানের উত্তর হ'ল এসকিউএল সহ এইচকিউএল ব্যবহার করা ।

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

থেকে এসকিউএল কোয়েরি বিবৃতি স্বতন্ত্র ROUTE_ID এবং একটি তালিকা হিসাবে ইনপুট পেয়েছিলাম। এবং IN ক্যোয়ারী IN (তালিকা) থেকে পৃথক TO_CITY ফিল্টার করুন।

রিটার্ন টাইপ হ'ল সত্তা বিন টাইপ। সুতরাং আপনি এটি AJAX এ যেমন অটো কমপ্লেন্টে করতে পারেন ।

সব ঠিক আছে


1

আপনি নিজের মতো করে মানদণ্ড নির্মাতায় স্বতন্ত্র কীওয়ার্ডটি করতে পারেন।

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

এবং আপনার মডেল শ্রেণিতে ফিল্ড কনস্ট্রাক্টর তৈরি করুন।


0

আপনার নির্বাচিত বিবৃতিতে যদি কাস্টম ডিটিওর জন্য আপনার নতুন কীওয়ার্ড ব্যবহার করতে হয় এবং স্বতন্ত্র উপাদানগুলির প্রয়োজন হয় তবে নীচের মতো নতুনের বাইরে নতুন ব্যবহার করুন-

select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...

0

আপনি কেবল আলাদা করার পরিবর্তে গ্রোপ বাই যুক্ত করতে পারেন

@Query(value = "from someTableEntity where entityCode in :entityCode" +
            " group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.