سؤال

أنا أبحث عن باني HQL في جافا.أريد أن أتخلص من الأشياء مثل:

StringBuilder builder = new StringBuilder()
    .append("select stock from ")
    .append( Stock.class.getName() )
    .append( " as stock where stock.id = ")
    .append( id );

أنا أفضل أن يكون شيئا مثل:

HqlBuilder builder = new HqlBuilder()
    .select( "stock" )
    .from( Stock.class.getName() ).as( "stock" )
    .where( "stock.id" ).equals( id );

لقد بحثت قليلا ، وأنا لا يمكن العثور على واحد.

كتبت سريعة و البكم HqlBuilder الذي يناسب احتياجات بلدي الآن ولكن أود أن العثور على واحد التي لديها المزيد من المستخدمين و الاختبارات من لي وحده.

ملاحظة:أود أن تكون قادرة على أن تفعل أشياء مثل هذا وأكثر ، وهو ما فشلت في القيام به مع معايير API:

select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.someValue = bonus.id

ie.حدد جميع الأسهم التي المنشأة someValue نقاط أي مكافأة من مكافأة الجدول.

وذلك بفضل!

هل كانت مفيدة؟

المحلول

@سيباستيان روكا-Serra
الآن نحن في مكان ما الخرسانة.نوع من الانضمام تحاول فعله ليس من الممكن حقا من خلال معايير API ، ولكن دون الاستعلام يجب أن تفعل نفس الشيء.أولا عليك إنشاء DetachedCriteria من أجل مكافأة الجدول ، ثم استخدام IN المشغل someValue.

DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class);
List stocks = session.createCriteria(Stock.class)
    .add(Property.forName("someValue").in(bonuses)).list();

هذا هو ما يعادل

select stock
from com.something.Stock as stock
where stock.someValue in (select bonus.id from com.something.Bonus as bonus)

الجانب السلبي الوحيد أن يكون إذا كان لديك إشارات إلى جداول مختلفة في someValue و ID الخاص بك ليست فريدة من نوعها في جميع الجداول.ولكن الاستعلام الخاص بك سوف تعاني من نفس الخلل.

نصائح أخرى

لا معايير API تفعل ذلك بالنسبة لك ؟ يبدو تماما مثل ما كنت طالبا.

لنوع آمنة نهج مشكلتك تنظر Querydsl.

مثال الاستعلام يصبح

HQLQuery query = new HibernateQuery(session);
List<Stock> s = query.from(stock, bonus)
  .where(stock.someValue.eq(bonus.id))
  .list(stock);

Querydsl يستخدم ملائمة للحصول على رمز جيل مثل JPA2 ويدعم JPA/السبات ، JDO, SQL و جافا مجموعات.

أنا معيل من Querydsl ، لذلك هذا الجواب منحازة.

لنوع آخر آمن الاستعلام dsl, أوصي http://www.torpedoquery.org.المكتبة لا يزال شابا ولكنه يوفر نوع السلامة مباشرة باستخدام الكيان الطبقات.وهذا يعني في وقت مبكر أخطاء برنامج التحويل البرمجي عند الاستعلام لم يعد ينطبق قبل من إعادة بيع ديون أو إعادة تصميم.

كما أنني قدمت لك مثالا على ذلك.أعتقد من مشاركاتك التي فيها تحاول أن تفعل فرعي تقييد, لذلك أنا على سبيل المثال على ذلك:

import static org.torpedoquery.jpa.Torpedo.*;

Bonus bonus = from(Bonus.class);
Query subQuery = select(bonus.getId());

Stock stock = from(Stock.class);
where(stock.getSomeValue()).in(subQuery);

List<Stock> stocks = select(stock).list(entityManager);

يبدو أنك تريد استخدام معايير الاستعلام API بنيت في السبات.لا فوق الاستعلام انها تبدو مثل هذا:

List<Stock> stocks = session.createCriteria(Stock.class)
    .add(Property.forName("id").eq(id))
    .list();

إذا لم يكن لديك الوصول إلى السبات الدورة حتى الآن ، يمكنك استخدام 'DetachedCriteria' مثل ذلك:

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class) 
    .add(Property.forName("id").eq(id));

إذا أردت الحصول على كل الأوراق المالية التي تم مكافأة مع هوية محددة يمكن القيام بما يلي:

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class)
     .createCriteria("Stock")
          .add(Property.forName("id").eq(id)));

لمزيد من معلومات تحقق معايير الاستعلامات من السبات مستندات

@سيباستيان روكا-Serra

select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.bonus.id = bonus.id

هذا مجرد الانضمام.السبات يفعل ذلك تلقائيا ، إذا و فقط إذا كنت قد حصلت على التعيين بين Stock و Bonus إعداد و إذا bonus خاصية Stock. Criteria.list() سيعود Stock والأشياء لك فقط اتصل stock.getBonus().

ملاحظة إذا كنت تريد أن تفعل أي شيء مثل

select stock
from com.something.Stock as stock
where stock.bonus.value > 1000000

تحتاج إلى استخدام Criteria.createAlias().سيكون شيئا مثل

session.createCriteria(Stock.class).createAlias("bonus", "b")
   .add(Restrictions.gt("b.value", 1000000)).list()

معايير API لا توفر جميع وظائف افايابلي في HQL.على سبيل المثال, لا يمكنك أن تفعل أكثر من انضمام أكثر من نفس العمود.

لماذا لا تستخدم اسمه استفسارات?نظرة أكثر نظافة:

Person person = session.getNamedQuery("Person.findByName")
                             .setString(0, "Marcio")
                             .list();

كتبت GPL ان الحل ميرو والتي يمكن بسهولة بناء يناسب الوضع الخاص بك.

الاستخدام:

QueryBuilder qb = new QueryBuilder();
qb.select("img");
qb.from("Image", "img");
qb.join("img.pixels", "pix", true, false);

// Can't join anymore after this
qb.where(); // First
qb.append("(");
qb.and("pt.details.creationTime > :time");
qb.param("time", new Date());
qb.append(")");
qb.and("img.id in (:ids)");
qb.paramList("ids", new HashSet());
qb.order("img.id", true);
qb.order("this.details.creationEvent.time", false);

وهي بمثابة آلة الدولة "select->من>تاريخ->أين->النظام" ، إلخ.ويحافظ مع المعلمات الاختيارية.كانت هناك عدة استفسارات معايير API لا يمكن أن تؤدي (انظر HHH-879) ، وذلك في نهاية الأمر كان أبسط لكتابة هذه الطبقة الصغيرة إلى التفاف بـ stringbuilder.(ملاحظة:هناك تذكرة HHH-2407 واصفا السبات فرع والتي ينبغي أن توحيد اثنين.بعد ذلك, ربما من شأنه أن يجعل الشعور إلى إعادة زيارة معايير API)

نلقي نظرة على البحث حزمة المتاحة من السبات-عام-dao المشروع.هذا هو لائق جدا HQL باني التنفيذ.

أعرف أن هذا الموضوع هو قديمة جدا, ولكن أنا أيضا كنت أبحث عن HqlBuilder ووجدت هذا "شاشة التوقف" المشروع
ليس ويندوز شاشة انها "معمل نظام إدارة المعلومات (LIMS) عالية الإنتاجية الفحص (HTS) المرافق التي تؤدي جزيء صغير و رني الشاشات."

أنه يحتوي على HQLBuilder أن تبحث جيدة جدا.
هنا هو قائمة عينة من الأساليب المتاحة:

...
HqlBuilder select(String alias);
HqlBuilder select(String alias, String property);
HqlBuilder from(Class<?> entityClass, String alias);
HqlBuilder fromFetch(String joinAlias, String joinRelationship, String alias);
HqlBuilder where(String alias, String property, Operator operator, Object value);
HqlBuilder where(String alias, Operator operator, Object value);
HqlBuilder where(String alias1, Operator operator, String alias2);
HqlBuilder whereIn(String alias, String property, Set<?> values);
HqlBuilder whereIn(String alias, Set<?> values);
HqlBuilder where(Clause clause);
HqlBuilder orderBy(String alias, String property);
HqlBuilder orderBy(String alias, SortDirection sortDirection);
HqlBuilder orderBy(String alias, String property, SortDirection sortDirection);
String toHql();
...

الآن متاحة أيضا القياسية JPA نوع آمنة الاستعلام و أقل القياسية ولكن أيضا جيدة كائن الاستعلام

أمثلة:

JPA نوع آمنة

EntityManager em = ...
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Stock> c = qb.createQuery(Stock.class);
Root<Stock> = c.from(Stock.class);
Predicate condition = qb.eq(p.get(Stock_.id), id);
c.where(condition);
TypedQuery<Stock> q = em.createQuery(c); 
List<Stock> result = q.getResultList();

كائن الاستعلام

EntityManager em = ...
ObjectQuery<Stock> query = new GenericObjectQuery<Stock>(Stock.class);
Stock toSearch = query.target();
query.eq(toSearch.getId(),id);
List<Stock> res = (List<Stock>)JPAObjectQuery.execute(query, em);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top