12.JPA - Java Persistence API

ORM Kavramı

ORM(Object Relation Model) kavramı genel olarak veri tabanın elde bulunan sınıflarla eşleştirilmesi anlamında kullanılmaktadır.Aralarında benzerlik olsa da nesne yönelimli database yönetim sistemleriyle karıştırılmamalıdır. ORM kavramı birçok yazılım platformunda desteklendiği gibi Java’da da temel düzeyde JPA(Java Persistent API) ile gerçekleştirilebilmektedir. JPA Java’da bu işi gerçekleştirmek için en temel araçtır. Ancak JPA kullanılarak gerçekleştirilmiş pek çok kütüphane bulunmaktadır. Örneğin Hibernate, Eclipse Link gibi… Burada önce Eclipse Link sonra da Hibernate teknolojisi ele alınacaktır.

JPA Teknolijisi

JPA kullanarak oluşturulan sınıflara Entity(Varlık) denilmektedir. Sınıftan başlanarak veri tabanı oluşturulursa bu durumda burdaki sınıflara POJO (Plain Old Java Object) sınıfları denilmektedir. Şüphesiz JPA kullanılırken veritabanına erişim JDBC üzerinden yapılacağından ilgili veritabanı yönetim sistemine ilişkin JAR dosyasınında projeye dahil edilmesi gerekmektedir.

JPA Projesinin Oluşturulması

(VYS = Veritabanı Yönetim Sistemi)

Burada Eclipse Link kullanılarak Eclipse IDE’si ile JPA projesi oluşturulması anlatılacaktır. Adımlar basitçe şöyledir. JPA Projelerinin kolay yapılandırması için Eclipse EE versiyonu kullanılabilir.

  • Proje Seçeneklerinden JPA Project seçilir. Çıkan pencerede target runtime kısmına sistemde yüklü olan çalıştırma ortamının yeri verilmelidir.
  • Bu admından sonra next tuşuna basılarak download library bölümünden Eclipse Link’in son hali seçilebilir ve download edilir.
  • Kullanılıcak VYS ne ise o VYS ilişkin JAR dosyası eklenir. Bir JPA projesinde persistence.xml denilen bir bildirim dosyası bulunmaktadır. Bu bildirim dosyasında VYS ilişkin bağlantı bilgileri, hangi sınıfların entity olacağı gibi bilgiler, eğer tablolar yoksa yaratılması gerekliliğine ilişkin bilgiler yazılır. Eclipse IDE'sinde bu xml dosyası görsel olarak çeşitli tablarla işlem yapılabilir.
  • Persistence.xml içeresinde Class direktifi hangi sınıfların varlık olarak kullanılacağının bildirilmesi için kullanılır. Buradaki sınıf isimleri nitelikli-paket isimi ile birlikte (Fully-Qualified) verilmelidir. Properties isimli eleman içerisinde ise Property elemanlarında VYS'ne ilişkin bir takım bildirimler yapılmalıdır.
    <class>org.csystem.entity.Student<class>
    

Anahtar Notlar: Veritabanı teorisinde her bir tablonun birincil anahtarı olması beklenir. Dolayısıyla JPA teknolojisi de Primary Key tanımlanmamış olan bir tablo için çalışamamaktadır. Yani programcının birincil anahtarı belirlemesi gerekmektedir. Bu işlem aşağıdaki gibi yapılmaktadır.

JPA için özel tasarlanmış Annotation sınıflar bulunmaktadır. Bu Annotation'lar içerisinde @Id Annotation'ı bir field'ın Primary Key olup olmadığına ilişkin bilginlendirme yapmaktadır. Yani bir veri elemanı üzerinde @Id Annotation'ı ile onun Primary Key olduğunu söyleriz. @GeneratedValue annotationın Strategy isimli propertysi ile örneğin otomatik artan bir numara olması bilgisi verilebilir.

@Entity
public class Student {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  @Column(name="student_id")
  private int m_id;
}

Burada @Id ile m_id veri elemanı tablo için Primary Key yapılmıştır, @GeneratedValue ile otomatik artan özelliğe sahip olması sağlanmıştır. @Column annotation sınıfı ile bir veri elemanının tabloda hangi isimde olacağı belirlenmektedir. JPA Pojo sınıfları, Bean özelliklerini gerçeklemelidir.

Bir Entity Sınıfın kullanılabilmesi için pratikte servis sınıfları kullanılmalıdır. Bir JPA varlığı kullanabilmek için EntityManagerFactory isimli bir fabrika sınıfından faydalanılır. Bu Manager yardımıyla EntityManager sınıf nesnesi oluşturulur.

Anahtar Notlar: Bir nesneyi yaratmak için new operatoru kullanılması yerine bir Factory sınıfından elde edilmesi kalıbı, GOF (Gang of Four) tasarım kalıplarından biridir.

EntityManagerFactory sınıfı Persistence sınıfının createEntityManagerFactory sınıfı ile elde edilebilir. Bu metod persistence.xml içerisinde <persistence-unit> elemanına ilişkin ismi istemektedir. Buna göre bu fabrikadan elde edilen nesneler bu persistent unit bildirimine ilişkin nesneler olacaktır.

001-SampleEclipseLink

EntityManager sınıfının find isimli metodu ile ilgili sınıfa ilişkin id değerine göre nesne aranabilir. Eğer nesne bulunamazsa bu metod null döndürmektedir. find işlemi için ayrıca bir transanction'da olunmasına gerek yoktur.

Güncelleme işlemi için yapılacak şey aslında çok basittir. Veritabanında ilgiyi veriye ilişkin nesne elde edilir ve o nesne üzerinde değiştirme işlemleri yapılır ve tekrar commit edilerek veritabanına yazılması sağlanır.

Silme işlemi için yine bir transaction içerisinde remove metodu kullanılmalıdır. remove metodu ile silindikten sonra yine commit işlemi yapılmalıdır.

Sınıf Çalışması: Aşağıdaki gibi menusu olan ve öğrencileri ekleyen bir uygulamayı yazınız.

  1. Ekle
  2. Sil
  3. Güncelle
  4. Listele
  5. Çıkış

Çözümü 002-SampleStudentInformation

JPA ile Türetme İşlemleri

JPA içerisinde türetme ilişkisi 3 farklı şekildeki strateji ile belirlenebilir:

  1. Single Table
  2. Join Table
  3. Table per Class

Single Table Strategy

Burada tek bir tablo oluşturulur, programcının türemiş sınıflara vermiş olduğu discriminator value (ayırt etme değeri) ile tablo içerisinde bu türler ayrıştırılır. Programcı taban sınıfı yazarken @DiscriminatorColumn annotation sınıfı ile ayırt edilecek sınıfın bilgisi verilebilir. Taban sınıf içerisinde @Inheritence annotation sınıfı ile strateji inheretince type türünden verilebilir.

003-InheritanceSingleTableStrategy

Joined Table Strategy

Bu stratejide unique bir değer ile referans edilen bir kolon kullanılmaktadır. Bu stratejiye göre türemiş sınıf sayısı kadar tablo oluşturulacaktır bununla taban sınıfa ilişkin de bir tablo oluşturulmaktadır. Bu tablolarda taban sınıftandan bir değer primary key olarak söylenecektir. Şüphesiz bu değer taban sınıfın primary key değeri olmalıdır.

004-InheritanceJoinedTableStrategy

Table Per Class Strategy

Bu stratejide her bir türemiş sınıf için taban sınıfla birlikte bilgilerini içeren ayrı bir tablo yaratılır. Burada yalnızca inheritence bildirimi yapılması ve türemiş sınıflarda gerekirse gereken bildirimlerin yapılması yeterlidir. Ayrıca taban sınıfa ilişkin tabloda kullanılma ihtimaline karşılık yaratılmaktadır.

005-InheritanceTablePerClassStrategy

JPA'in Diğer Proje Çeşitlerinde Kullanımı JPA uygulamaları diğer projeler ile de kullanılabilmektedir. Bunun için normal proje açma adımları içerisinde Configuration bölümünde JPA seçilerek tamamlanabilir.

Sınıf Çalışması: JoinTable strateji ile oynatılmış, Employee-Manager-Worker hiyerarşisinde JPA ile 2 form oluşturarak veri tababına ekleme sağlayan dinamik web uygulamasını yazınız.

006-InsertEmployeesJPA

JPA ile Varlıklar Arasındaki İlişkiler

JPA iki varlık arasında

  1. 1-n (onetomany)
  2. n-1 (manytoone)
  3. 1-1 (onetoone)

ilişkileri desteklemektedir.

ManyToOne İlişkisi

Bu ilişki adından da anlaşılabileceği gibi bir entity'e karşılık diğer entity'den birden fazla veri olabilmesi anlamına gelmektedir. Buna göre ManyToOne annotion isimli sınıf ile bir sınıf içerisinde diğer sınıf türünden veri elemanı yerleştirilir ve işlem kolaylıkla devam ettirilebilir. ManyToOne ilişkisinde özellikle veritabanında bir id'ye karşılık gelen yabancı anahtar(foreign key) sınıflar düzeyinde "Aggregation" ilişkisiyle tanımlanmalıdır. Bu işlem şu şekilde yapılabilir. Bu ilişkide bir çalışanın hangi departmanda olduğu düşünülmelidir.

007-SampleMTORelationShip

Anahtar Notlar: ManyToOne ilişkisinde Aggregation olarak birleştirilen sınıfa ilişkin alan adı @JoinColumn isimli annotion içerisinde verilebilir.

OneToMany İlişkisi

Bu ilişki bir varlığa karşılık birden fazla eşleşen başka bir varlığın olması durumunu açıklar. Buna göre ManyToOne ilişkisinin tersine diğer sınıfta bir Collection veri elemanı tutulur. Diğer sınıfta ise herhangi birşey tutulmaz. Bu ilişkide örneğin bir departmanda çalışanlar düşünülmelidir.

008-SampleOTMRelationShip

Bu ilişkide iki tabloya karşılık 2'sinin birleştirildiği 3. bir tabloda bulunmaktadır. Bu yöntem diğer yönteme göre bir çok durumda daha etkin çalışmasına karşın veritabanı tarafında yönetilmesi zordur.

OneToOne İlişkisi

Bu ilişkide bir varlığın veri elemanı olan diğer varlık OneToOne ilişkisine sahiptir.

009-SampleOTO

Sınıf Çalışması 006 örneğine Department tablosunu OneToMany ilişkisi ile ekleyen ve departmanı bir dropdown list ile seçilmesini sağlayan uygulamayı belirli departmanlar için yazınız.

Bilindiği gibi find metodu ile ancak tek bir varlığa ilişkin data elde edilebilir. Buna göre eğer birden fazla data elde edilmesi gerekiyorsa ilgili select komutunun veritabanına gönderilmesi gerekmektedir. Bu işlemin birden fazla yapılma yöntemi vardır;

  1. JQL (JPA Query Language) kullanmak.
  2. Aşağı seviyeli sorgular ile dataları elde etmek.

Birinci yöntemde createQuery isimli metot yardımıyla hangi varlığa ilişkin sorgulama işleminin yapılacağı verilebilir.

Query q = em.createQuery("select d.name from Departments d", Department.class);

List list = q.getResultList();

Burada kullanılan sorgulama kodu klasik SQL sorgularına benzese de JQL olarak adlandırılmaktadır ve klasik sorgulardan biraz farklı olabilmektedir. Aslında bu yöntem JPA kullanılarak implemente edilmiş birçok framework'te tercih edilmektedir, örn hibernate.

Not: JQL içerisinde tablo ismi yerine sınıf ismi kullanılmalıdır. Örn.

Query q = em.createQuery("select d.name from Departments d", Department.class);

burada Department varlık ismidir ve zaten hangi tabloyla ilişkilendirildiği bellidir. Bunun sebebi bir varlığa ilişkin illa da bir tablo olması gerekmemesidir.

010-

Bu uygulamada yazılan servis nesnesi her client için yeniden yazılmaktadır. Böylece farklı clientlar aynı nesneleri görmezler ayrıca programcının bir senkranizasyon yapma zorunluluğu da kalmaz. Bu uygulamada formlar üzerinden girişlerin geçerliliği ve tasarımına dikkat edilmemiştir.

ManyToMany İlişkisi

Bu ilişki birden fazla varlığa ilişkin birden fazla diğer varlığın olabilmesi ilişkisidir. Bu yapı oluşturulurken @ManyToMany'den faydalanılır. İki bağımsız varlık arasında çokluk ilişkisi olduğundan bu sınıflar içerisinde Set arayüzü kullanılır. Set arayüzü verileri sırasız(unordered) olarak tutulduğu bir veri yapısına ilişkin arayüzdür. Bu yapının sonucunda iki varlığa ilişkin iki adet tablo ve bunları birleştiren yani iki tablonun birincil anahtarlarının yabancı anahtar olarak bulunduğu bir tablo yaratılmaktadır.

ManyToMany ilişkisinde başka tablolarda var ise bunlarda ayrıca belirlenebilir.

results matching ""

    No results matching ""