استخدم عددًا أقل من الأعمدة في استعلام SQL من خلال الإسبات الإسقاطي على الكيان الذي له علاقة ManyToOne

StackOverflow https://stackoverflow.com/questions/1618394

سؤال

أحاول إنشاء SQL أصغر لتجنب "select * from A" الذي يتم إنشاؤه افتراضيًا لمعايير السبات.

إذا استخدمت حقولًا بسيطة (لا توجد علاقة)، ​​من خلال "المحولات"، فيمكنني الحصول على SQL هذا:

select description, weight from Dog;

مرحبًا، لدي هذا الكيان:

@Entity
public class Dog
{
   Long id;
   String description;
   Double weight;
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "person_id", nullable = false)
   Person owner;
}

@Entity
public class Person
{
   Long id;
   String name;
   Double height;
   Date birthDate;
}

هدفي هو الحصول على هذا:

select description, weight, owner.name from Dog

لقد جربت ذلك باستخدام المعايير (والمعايير الفرعية):

Criteria dogCriteria = sess.createCriteria(Dog.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("description"), description);
proList.add(Projections.property("weight"), weigth);
dogCriteria.setProjection(proList);

Criteria personCriteria = dogCriteria.createCriteria("owner");
ProjectionList ownerProList = Projections.projectionList();
ownerProList.add(Projections.property("name"), description);    
dogCriteria.setProjection(ownerProList);  //After this line,  debugger shows that the
                                          //projection on dogCriteria gets overriden
                                          //and the query fails, because "name" is
                                          //not a field of Dog entity.

كيف يمكنني استخدام الإسقاطات للحصول على SQL أصغر وأعمدة أقل؟شكرا لك مقدما.

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

المحلول

أولاً،

select description, weight, owner.name from Dog

SQL غير صالح.يجب أن يكون شيء من هذا القبيل

select description, weight, Person.name
 from Dog join Person on Dog.person_id = Person.id

بدلاً من.ثانيا لماذا؟على الرغم من أنه من الممكن أن تفعل ما تريد (انظر أدناه)، إلا أنه من المطول للغاية القيام بذلك عبر Criteria API ولن تحصل على أي شيء لإظهاره.إن التوفير في نقل البيانات لبضعة أعمدة لا يكاد يذكر إلا إذا كانت الأعمدة المذكورة عبارة عن نقاط ضخمة أو كنت تحدد مئات الآلاف من السجلات.وفي كلتا الحالتين هناك طرق أفضل للتعامل مع هذه المشكلة.

Anywho، للقيام بما تريد للمعايير، تحتاج إلى الانضمام إلى الجدول المرتبط (الشخص) عبر الاسم المستعار وتحديد الإسقاط على رئيسي المعايير باستخدام الاسم المستعار المذكور:

Criteria criteria = session.createCriteria(Dog.class, "dog")
 .createAlias("owner", "own")
 .setProjection( Projections.projectionList()
   .add(Projections.property("dog.description"))
   .add(Projections.property("dog.weight"))
   .add(Projections.property("own.name"))
 );

هناك وصف ومثال لما سبق في وثائق توقعات المعايير.ضع في اعتبارك أنه عند تنفيذ المعايير المذكورة أعلاه، فإنها ستعيد قائمة بمصفوفات الكائنات.سوف تحتاج إلى تحديد أ محول النتيجة من أجل تحويل النتائج إلى أشياء فعلية.

نصائح أخرى

لم أجربه بنفسي بعد، ولكن أعتقد أنه يمكنك أيضًا استخدام مُنشئ آخر في الكيان الخاص بك (Pojo) وتمرير الأعمدة هناك.يرى https://www.thinkts-on-Java.org/hibernate-best-practices/ الفصل "1.2 بوجو" للحصول على تعليمات مفصلة.على الرغم من أنه ليس من الواضح بعد ما إذا كان هذا يعمل أيضًا مع علاقات ManyToOne أيضًا.سأحاول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top