6 Ocak 2012 Cuma

Hibernate ile DAO ve Castle.ActiveRecord kullanımı

Hibernate çok tercih edilen ORM kütüphanlerinden biris. Kuşbakışı mimarisini buradan aldım.


Her türlü XML dosyasında olduğu gibi hibernate konfigürasyonda dosyası da karmaşık gelebiliyor. Önemli bölümlerini göstern şekli buradan aldım.

Bir diğer önemli konfigürasyon özelliği ise hibernate tarafından üretilen sql komutlarının gösterilebilmesi. Onun konfigürasyonunu gösteren şekli ise buradan aldım. show_sql = true yapmak yeterli.


Hibernate ile iki kademeli önbellek kullanabilme imkanı da var. Yukarıdaki şekilde gösterilmediği için aşağıya buradan aldığım bir şekil daha ekledim.


Session Factory:
Yaratılması pahalı bir nesne olup veritabanı başına bir tane yaratılmalıdır.

Session:
Veritabanına açılan kısa süreli bağlantılar gibidir. Bir session şu durumlarda bulunabilir.


Doğrudan Hibernate Kullanırken Session ve Transaction İlişkisi

Bir session nesnesinin ne olduğu ve transaction ile arasındaki ilişki burada çok güzel anlatılmış.Burada unutulmaması gereken nokta session ve transactionlar birbirlerinden ayrılamaz ikililerdir.

Problemin özeti şu : JDBC ile veritabanına bağlantı açılması ile aslında transaction başlıyor. Ancak Hibernate default olarak bağlantının autocommit özelliğini false yapıyor. Daha sonra biz Hibernate ile session'ı kapatırsak transaction commit edilmeden bağlantıyı kapatıldığı için ne olacağı belirsiz.Transaction kullanılmadan sadece session açıp kapamanın neticesi undefined (yani tanımsız, örneğin oracle için çalışırken başka bir veritabanı için çalışmayabilir) ve bu konuyu açıklayan güzel bir örnek te burada var.

Dolayısıyla bir session nesnesinin açılıp kapatılması transaction'ının tamamlandığı anlamına gelmiyor.

Yani bir session nesnesi alındıktan sonra illaki bir transaction nesnesi yaratıp, daha sonra commitTransaction() metodunu çağırmak gerekiyor. Aynı konuyu açıklayan bir diğer yazıyı ise burada bulabilirsiniz.

Kullanım için örnek kodları burada bulabilirsiniz.

Tüm bu detayları daha kolay hale getirmek için Spring Framework ile gelen HibernateTemplate sınıfı da kullanılabilir. Buradan aldığım şekilde de görüldüğü gibi HibernateTemplate template tasarım örüntüsünü kullanır ve SessionFactory sınıfını kullanarak veritabanına erişimi sağlar.

Fikir olsun diye HibernateTemplate sınıfına SessionFactory sınıfının nasıl inject edilebileceğini gösteren bir şeklide buradan aldım.

Aslında hemen hemen aynı mantıkta çalışan JDBCTemplate sınıfı da aşağıda. Aradaki tek fark hibernate için SessionFactory enjekte edilirken, JDBC için data source enjekte ediliyor.


Eğer Hibernate ile yüklenen bir nesne session kapatıldıktan sonra kullanılmaya kalkılırsa hibernate LazyInitializationException atabilir. Burada da anlatıldığı gibi bazen hibernate ile yüklenen nesne yerine nesnenin princil anahtarını ve nesne sınıfını saklamak daha iyi olabilir.

Önbellek:

İki kademelidir. Aşağıda her iki belleği de anlatmaya çalıştım.

Birincil Önbellek
Bu konu için Hibernate Birincil Önbellek başlıklı yazıya göz atabilirsiniz.
 
İkincil Önbellek
İkincil önbellekle ilgili kısmı Hibernate ve İkincil Önbellek başlıklı yazıya taşıdım.

Nesnelerin Yönetilmesi

Hibernate nesnelerinin yönetilmesi buradan aldığım şekilde gayet güzel açıklanmış.


Aynı şeyi anlatan bir başka şekli ise burada buldum.


Nesnelerin Java veya hibernate kullanan başka bir dilden SQL'e çevirilmesi için hibernate bize bazı built-in type sınıfları sağlar. Bunları burada buldum ve aşağıya ekledim.



SQL'e çevirilirken Hibernate bazı optimizasyonlar yapılmasına da imkan tanır. Örneğin buradan aldığım bir örnekte de açıklandığı gibi bazı veritabanlarındaki tablolar çok sayıda sutün ihtiva ederler. Bir nesnede yapılan küçük bir değişiklik bile kocaman bir SQL ile tüm satırların güncellenmesine sebep olabilir. Bu durumdan kurtulmak ve sadece değişen sutünlar için SQL üretilsin isteniyorsa buradan aldığım örnekte de gösterildiği gibi sutünlarar dynamicInsert, dynamicUpdate özelliği atanabilir.


HQL
HQL için HQL (Hibernate Query Language) başlıklı yazıya göz atabilirsiniz.

DAO ve Castle.ActiveRecord

Hibernate kullanırken izlenen iki tane temel yöntem var. İlki Data Access Object (DAO), diğeri ise ActiveRecord tasarım örüntüleri. ActiveRecord örüntüsünü gerçekleştiren kütüphanelerden birisi ise Caste ActiveRecord projesi.


Aşağıda iki yöntemi de kullanarak çizilmiş bir UML sınıf diagramı var.




Castle.ActiveRecord kullanırken sınıfımı ana bir ActiveRecordBase sınıfından türetmek yeterli.

DAO yönteminde ise her sınıfa karşılık bir de DAO sınıfı yazmak gerektiği için proje çok kalabalık hale geliyor. Aşağıdaki örneği buradan aldım. BusinessObject TransferObject'i (yani yukarıdaki şekilde MyClass'a denk geliyor) veritabanına yazmak veya veritabanından okumak için DataAccessObject'i kullanmak zorunda.




Bu yüzden bence Castle.ActiveRecord, DAO'ya göre kullanması çok daha kolay olan bir yöntem.

ActiveRecord Session ve Transaction İlişkisi

Castle.ActiveRecord kullanılsa bile altta halen NHibernate kullanılmaya devam ettiği için yukarıda anlatılan session,transaction ilişkisi devam ediyor. Ancak Castle.ActiveRecord buradan aldığım şu cümlede de anlatıldığı gibi transaction açma/kapama işlemini kendi hallediyor.

When ActiveRecord is about to delegate something to NHibernate it checks if there is a ISession instance available and if not, one is created and disposed as soon as the operation is completed.

Eğer transaction açma/kapama işlemi dışarıdan kontrol edilmek isteniyorsa ActiveRecord duruma SessionScope denilen bir sınıf ile çare bulmuş.

Her iki durumu da açıklayan bir şekili aşağıda gösterdim.

Bir diğer fark ise Castle.ActiveRecord ile lazy loading false olarak başlıyor. Bu durumda şöyle açıklanmış.
All relation attributes (except BelongsTo) have a Lazy property that is false by default. You just need to enable Lazy along the same lines as described above.

Hiç yorum yok:

Yorum Gönder