NativeQuery

All lectures for UZ purposes
Daraja, Dars
Mavjud

3.1 Tanishtirish

Yana bir foydali narsani aytib o'tmoqchiman – bu NativeQuery. Bilganingdek, NativeQuery yordamida native SQLda so'rovlar yozish mumkin. Shunga qaramay, eng qiziq narsa shundaki, so'rov natijasini olishda class mappingdan foydalanmaslik ham mumkin.

Eng yaxshi usul bunga misol keltirishdir:

List<Object[]> persons = session.createNativeQuery("SELECT * FROM Person").list();

Bu misolda biz so'rov natijasi qatorlariga mos keladigan classni o'tkazmayapmiz, uning o'rniga faqat Object[] obyekti ishlatilmoqda.

Agar jadvalning bir nechta ustuni kerak bo'lsa, bu foydali bo'lishi mumkin. Misol:


List<Object[]> persons = session.createNativeQuery("SELECT id, name FROM Person").list();
 
for(Object[] person : persons) {
    Number id = (Number) person[0];
    String name = (String) person[1];
}

Bu JDBC uslubiga o'xshaydi, bunda sen ResultSet obyektini olib, uning qatordagi ma'lumotlarini o'qiysan.

Biroq Hibernate bu ishni yanada ishonchli qilishi mumkin bo'lgan turli usullarni taklif qiladi. Masalan, chiqarish niyatidagi ustunlarning turini ko'rsatishingiz mumkin. Misol:


Query<Object[]> query = session.createNativeQuery("SELECT id, name FROM Person");
query.addScalar("id", StandardBasicTypes.LONG);
query.addScalar("name", StandardBasicTypes.STRING);
List<Object[]> persons = query.list();
 
for(Object[] person : persons) {
    Long id = (Long) person[0];
    String name = (String) person[1];
}

3.2 Entity mapping

Shuningdek, NativeQuery natijasini pars qilishda Hibernate foydalanishi kerak bo'lgan classni aniq ko'rsatishingiz mumkin. Buni bir nechta usullar bilan qilish mumkin.


Query<Person> query = session.createNativeQuery("SELECT * FROM Person")
    .addEntity(Person.class);
    .list();

Va albatta, eski yaxshi format:


Query<Person> query = session.createNativeQuery("SELECT * FROM Person", Person.class).list();

Birinchi usul Hibernate'ning yondashuvi, ikkinchi esa JPA yondashuvi. JPA yondashuvi qulayroq va ixchamroq, chunki bu standart Hibernate bir necha yillar mavjud bo'lganidan keyin yaratilgan. Hibernate rivojlandi va eski uslublarni qo'llab-quvvatlashga majbur bo'ldi, bu esa eski versiyalari bilan mosligini ta'minladi.

Aytgancha, Hibernate o'z yondashuvi yordamida so'rov natijasiga bir nechta classlarni mapping qilish imkonini beradi. Misol:


List<Phone> results = session.createNativeQuery(
    "SELECT {ph.*}, {pr.*}" +
    "FROM Phone ph" +
    "JOIN Person pr ON ph.person_id = pr.id")
.addEntity("ph", Phone.class)
.addJoin("pr", "ph.person")
.list();
 
for (Phone. phone : results) {
           	assertNotNull( phone.getPerson().getName() );
}

Ushbu yondashuv NativeQuery yordamida ma'lumotlar bazasidan ma'lumotlarni tezroq olish uchun ishlatilishi mumkin. Agar sen bilsang, ba'zi ustunlar kerak emasligini, ularni so'rovda belgilamasliging mumkin.

Shuningdek, barcha child entitylarni, hatto Hibernate Cache yoki LazyLoading mexanizmlaridan foydalanmoqchi bo'lsa ham, bir vaqtning o'zida yuklashing mumkin. Bundan tashqari, child entitylar bazada ko'plab ustunlarga ega bo'lishi mumkin va ularning faqat ba'zilarini tanlab olishing mumkin.

3.3 DTO-mapping

Shuningdek Hibernate natijani mapping qilishda Entity-classlardan foydalanmaslik imkoniyatini ham beradi. Annotatsiyaga ega bo'lmagan va har qanday jadval bilan mapping qilinmagan classlar.

Misol:


public class PersonSummaryDTO {
    private Number id;
    private String name;
 
    public Number getId() {
    	return id;
    }
 
    public void setId(Number id) {
    	this.id = id;
    }
 
    public String getName() {
    	return name;
    }
 
    public void setName(String name) {
    	this.name = name;
	}
}

List<PersonSummaryDTO> dtos = session.createNativeQuery(
    "SELECT p.id as \"id\", p.name as \"name\" FROM Person p")
.setResultTransformer(Transformers.aliasToBean(PersonSummaryDTO.class) )
.list();

PersonSummaryDTO clasida hech qanday annotatsiyalar bo'lmagani uchun, SQL so'rovidagi ustunlarning nomlari PersonSummaryDTO clasidagi maydonlarning nomlari bilan aynan mos kelishi kerak.

Bu juda foydali bo'lishi mumkin, agar sen faqat o'qish rejimida ulanadigan tashqi ma'lumotlar bazasidan ma'lumot o'qiyotgan bo'lsang. Ya'ni, 50+ ustunli jadvallar bilan bizning dasturning aloqasi borligini ta'minlashgan, ular denormalizatsiya qilingan shaklda ma'lumotlar yuklash tezligini oshirish uchun saqlanadi.

Yoki kimdir classlar iyerarxiyasini bir jadvalda saqlashga qaror qilgandir, lekin besh yil o'tgach, bu jadval shunchalik o'sib ketdiki, mana, sen ham unda nimadir topish qiyinlashmoqda. Sen bu jadvaldan bir nechta ustun (Id va foydalanuvchi ismi) tanlab olib, ulardan mijozga berishing lozim.

O'ylaymanki, sen tushunding, lekin bu mavzuga chuqurroq kirishmoqchi bo'lsang, qo'shimcha ma'lumotni quyidagi havoladan o'qishing mumkin:

Native SQL Queries

DTO-mapping haqida yana bir oz ko'proq video

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION