Saturday, April 7, 2012

PERSISTENCE API İNCELEME

Java persistence api java geliştiricilerine uygulamalarında kullanacakları veriye nesne
göreli olarak erişim imkanı sunar. Java persistence üç ana alana ayrılır:
• Java Persistence API
• Java sorgu dili
• Fiziksel veriyi nesne göreli eşleme

1- Varlıklar
Varlık java persistence ın tanım nesnesidir. Genel olarak varlık göreli veri tabanında
tablolara karşılık gelir ve her varlık örneği bu tabloda bir satırı ifade eder. Bir varlığın
persistent durumunu varlığın ilgili alanları yada özellikleriyle belirlenir. Bu alanlar ve
özellikler varlıkların belleklerde tutulan verilerle eşlenmesi için nesne/göreli eşleme
yöntemlerini kullanırlar.

1.1- Varlık Sınıflarının Gereksinimleri

Bir varlık sınıfı şu gereksinimleri izlemelidir:

• Sınıf javax.persistence.Entitiy bilgilendirmelerine uymalıdır.

• Sınıfın public veya private argümansız bir yapılandırıcısı olmalıdır. Sınıfın
bunun dışında başka yapılandırıcıları da olabilir.

• Sınıf final tanımlanmamalıdır. Hiçbir metot ve persistence bağımlı değişken
final tanımlanmamalıdır.

• Eger sınıfın bir kopyası ayrı bir nesne gibi bir değer olarak atanmak isteniyorsa
bu sınıf Serializable ara yüzünü gerçekleştirmelidir.

• Varlık sınıfları hem varlık sınıflarını hem de diğer sınıfları extend edebilir. Diğer
sınıflar da varlık sınıflarını extend edebilirler.

• Persistence ilişkili değişkenlerin tümü private, protected yada paket içi private
olarak tanımlanmalıdır ve direk erişimleri sınıf içi metotlarla olmalıdır.

1.2- Varlık Sınıfında Persistence İlişkili Alanlar ve Özellikler

Varlığın persistence durumu o varlığın değişkenleri veya JavaBeans-style özellikleri
tarafından erişilebilirdir. Bu alanlar ve özellikler şu türlerde olmalıdır

• Java İlkel Türleri
• Java.lang.String
• Diğer Türler:

o Java.math.BigInteger
o Java.math.BigDecimal
o Java.util.Date
o Java.util.Calendar
o Java.sql.Date
o Java.sql.Time
o Java.sql.TimeStamp
o Kullanıcı tanımlı türler
o byte[]
o Byte[]
o char[]
o Character[]

• Sayılı türler
• Diğer varlıklar ve/veya varlık grupları
• Gömülü sınıflar

1.2.1- Persistent Alanlar

Eger varlık sınıfı persistent alanlar içeriyorsa, Persistence çalışma zamanı
varlık sınıfı değişkenlerine doğrudan erişebilir.

1.2.2- Persistent Özellikler

Eger varlık sınıfı persistent özellikler içeriyorsa, varlık JavaBeans in metot
çevirimlerini takip etmelidir. JavaBeans-style özellikleri getter ve setter methodları
kullanır. Bu metotların isimleri varlık sınıfının değişken isimlerinden sonra tanımlanır.
Her özellik için bir getter (getProperty) ve setter (setProperty) bulunur. Tek değerli
özellikler için method şekli şöyledir:
Type getProperty()
void setProperty(Type type)

1.3- Varlıklarda Birincil Anahtarlar

Her varlık bir tek nesne tanımlayıcısına sahiptir. Örneğin bir tüketici varlığı
tüketici numarası ile simgelenir. Birincil anahtarlar istemcilerin ilgilendikleri varlık
nesnesine ulaşmalarını sağlar. Her varlığın bir birincil anahtarı olmak zorundadır. Bir
varlık basit yada bileşik birincil anahtara sahip olabilir. Basit birincil anahtarlar
javax.persistence.Id notasyonunu kullanırlar. Bileşik birincil anahtarlar bir birincil
anahtar sınıfında tanımlanmalıdır. Bileşik birincil anahtarlar
javax.persistence.EmbeddedId ve javax.persistence.IdClass notasyonlarını
kullanırlar.
Birincil anahtarlar veya bileşik anahtarların özellik yada alanları şu türleri
kullanmalıdır:

• Java İlkel Türleri
• Java.lang.String
• Java.util.Date
• Java.sql.Date

Kayan noktalı gösterim birincil anahtarlar için asla kullanılmamalıdır.

1.3.1- Birincil Anahtar Sınıfları

Bir birincil anahtar şu özellikleri karşılamalıdır:

• Sınıfın erişim tanımlayıcısı public olmalıdır.

• Özellik tabanlı erişim kullanılıyorsa sınıfın özellikleri public yada protected
olmalıdır.

• Sınıfın bir public yapılandırıcısı olmalıdır.

• Sınıf hashCode() ve equals(Object other) metotlarını gerçekleştirmelidir.

• Bileşik birincil anahtarlar çoklu alan ve özelliklerle eşleşmiş olarak yada
gömülebilir sınıf şeklinde ifade edilmelidir.

• Eger birincil anahtar sınıfı bir varlığın alanları yada özellikleriyle eşleşmişse,
birincil anahtar sınıfının özellikleri ve alanlarının isimleri ve türleri o varlık
kümesinin isimleri ve türleriyle uyuşmalıdır.

public final class LineItemKey implements Serializable {

public Integer orderId;

public int itemId;

public LineItemKey() {}

public LineItemKey(Integer orderId, int itemId) {
this.orderId = orderId;
this.itemId = itemId;
}

public boolean equals(Object otherOb) {
if (this == otherOb) {
return true;
}

if (!(otherOb instanceof LineItemKey)) {
return false;
}

LineItemKey other = (LineItemKey) otherOb;
return (
(orderId==null?other.orderId==null:orderId.equals
(other.orderId)
)
&&
(itemId == other.itemId)
);
}

public int hashCode() {
return (
(orderId==null?0:orderId.hashCode())
^
((int) itemId)
);
}
public String toString() {
return "" + orderId + "-" + itemId;
}
}

Tablodaki kod bir bileşik birincil anahtar sınıfının gerçekleştirimidir. orderId ve itemId
değerleri birlikte tek olarak bir varlığı ifade eder.


1.4- Varlıklarda Çokluk Bağıntısı

Varlıklarda 4 çeşit çokluk vardır. Bire bir, bire çok, çoğa bir ve çoğa çok.
Bire-bir ilişki : Her varlığın bir özelliği başka bir bağıntının sadece tek bir özelliği ile
eşleştirilmişse bire bir ilişki vardır denir. Bire bir ilişkiler javax.persistence.OneToOne
biçimini kullanırlar.

Bire-çok ilişki : Bir varlığın bir özelliği bir başka varlığın birden fazla alanı ile
ilişkilendirilmiş olabilir. Bire çok ilişkiler javax.persistence.OneToMany biçimini
kullanırlar.

Çoğa-bir ilişki : Bir varlığın birçok özelliği bir başka varlığın yalnız bir alanı ile
ilişkilendirilmiş olabilir. Bu durumda çoğa bir ilişki vardır denir. Çoğa bir ilişkiler
javax.persistence.ManyToOne biçimini kullanırlar.

Çoğa-çok ilişki : Bir varlığın birçok özelliği bir başka varlığın birden fazla alanı ile
ilişkilendirilmişse çoğa çok ilişkiden söz edilir. Çoğa çok ilişkiler
javax.persistence.ManyToMany biçimini kullanırlar.

1.5- Varlık Bağıntılarının Yönü

Varlıklar arası ilişkiler iki yönlü yada tek yönlü olabilir. iki yönlü ilişkiler hem sahip
taraf hem de ters tarafa sahiptir. tek yönlü ilişkilerde ters taraftan söz edilmez,
yalnızca sahip taraf vardır. Persistence ın ilişkiye dair günlemeleri veri tabanında
nasıl yapacağı sahip tarafa bağlıdır.

1.5.1- İki Yönlü İlişkiler

İki yönlü ilişkilerde her varlığın başka bir varlığa ilişkin alan yada özelliği
bulunur.

İki yönlü ilişkiler şu kurallara uymalıdır:

• İlişkinin ters tarafı mappedBy elemanı kullanılarak sahip tarafa ait olmalıdır.

• Çoğa çok ve çoğa bir ilişkilerin çok tarafları mappedBy elemanı tarafından
tanımlanmamalıdır. Çok taraf her zaman sahip taraf olmalıdır.

• Bire bir iki yönlü ilişkilerde sahiplik yabancı anahtara sahip olan tarafa aittir.

• Çoğa çok ilişkilerde her iki yön de sahip taraf olabilir.


1.5.2- Tek Yönlü İlişkiler

Tek yönlü ilişkilerde yalnızca bir varlığın ilişki alanı yada özelliği bulunur. İlişki
alanı bulunan varlık ilişkili olduğu varlıktan haberdardır fakat ilişkili olunan varlığın
ilişki alanı olan varlıktan haberi olmaz.

2- Varlık Yönetimi

Varlıklar varlık yöneticisi tarafından yönetilirler. Varlık Yöneticisi
javax.persistence.EntityManager örnekleriyle ifade edilir. Her bir varlık yöneticisi
örneği persistence bağlamlarıyla birleşirler. Persistence bağlamının görev aralığının
içinde varlık örneklerinin yaratılması , üstelenmesi ve silinmesi bulunur.

2.1- Persistence Bağlamı

Persistence bağlamı, yönetilen varlık örneklerinin oluşturduğu bir yapıdır ve bu
yapı özel bir veri tabanında bulunur.

2.2- Varlık yöneticisi

Varlık yöneticisi, varlık örneklerini yaratır ve yok eder. Ayrıca, varlıkları temel
anahtarına göre bulur ve sorguların bu varlıklara uygulanmasını sağlar.


2.2.1- Varlık Yöneticisi Denetleyici Yönetimi

Herhangi bir varlık yöneticisinin persistence bağlamı denetleyici kullanarak
otomatik olarak çoğalır. Uygulamanın tüm bileşenleri tarafından kullanılan varlık
yöneticisi örneği Java Transaction Architecture (JTA) denilen işlemin içinde bulunur.
JTA işlemi diğer uygulamanın bileşenlerini de işin içine sokar. Bu JTA
işleminin bileşenleri persistence bağlamına erişmek ister. Bunun olması için varlık
yöneticisinin javax.persistence.PersistenceContext aracılığıyla uygulama
bileşenlerine enjekte edilmesi gerekir. Persistence bağlamı JTA işlemi sırasında
otomatik olarak artar ve varlık yöneticisi bu JTA işlemi sırasında Persistence bağlamı
ile aynı persistence parçasını işaret eder. Bu sayede uygulamanın bileşenleri varlık
yöneticisine parametre geçmek zorunda kalmaz sadece JTA işleminde değişiklik
yapmak yeterlidir. Java EE denetleyicileri buradaki yaşam döngüsünü yönetirler.
Varlık yöneticisi örnekleminin uygulama bileşenlerine enjekte edilmesi:

@PersistenceContext
EntityManager em;

2.2.2- Varlık Yöneticisi Uygulama Yönetimi

Persistence bağlamı uygulamanın bileşenlerinde otomatik olarak artmıyorsa
ya da varlık yöneticisinin yaşam döngüsü uygulama tarafından yönetiliyorsa bu
durum ortaya çıkar.

Varlık yöneticileri bir uygulama tarafından persistence bağlamına erişmek için
kullanılıyorsa ve JTA işleminde tarafından artırılmıyorsa kullanılır. Başka bir deyişle
varlık yöneticisi yeni ve izole olmuş persistence bağlamını oluşturur.Varlık yöneticisi
ve onun yarattığı persistence bağlamı uygulama tarafından yaratılır ve yok edilir.
Uygulamalar javax.persistence.EntityManagerFactory metodunu kullanarak
varlık yöneticisini oluşturur.

@PersistenceUnit
EntityManagerFactory emf;
EntityManagerFactory örneklemi kullanarak varlık yöneticisi oluşturulur.
EntityManager em =emf.createrEntityManager();

2.2.3- Varlık Yöneticisi Kullanarak Varlıkları Bulmak

EntityManager.find metodu kullanarak varlık biricik anahtarına göre
depolanmış varlıkları buluruz.

@PersistenceContext
EntityManager em;

public void enterOrder(int custID, Order newOrder) {
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}

2.2.4- Varlık Örneklem Yaşam Döngüsünün Yönetimi

Varlıklar üstündeki işlemleri varlık yönetici kopyalarıyla yönetiyoruz. Varlık
örneklemleri 4 durumda bulunabilir: yeni , yöneten , silinen ve ayıran durumlar.

Yeni varlık örneklemlerinin persistent kimlikleri yoktur ve varlık bağlamıyla
ilişkendirilecek durumda değillerdir.

Yöneten varlık örneklemlerinin persistent kimlikleri vardır ve varlık
bağlamlarıyla ilişkilendirilirler.

Ayıran varlık örneklemlerinin persistent kimlikleri vardır ve varlık bağlamıyla
ilişkendirilecek durumda değillerdir.

Silinen varlık örneklemlerinin persistent kimlikleri vardır ve varlık bağlamlarıyla
ilişkilendirilirler


2.2.4.1- Varlık Örneklemleri

Yeni varlık örneklemleri persistent metodu tarafından yönetilirler. Yani persist
metodu tamamlanmış işlem gerçekleştiği zaman varlığın bilgileri bir veri tabanında
saklanır.
@PersistenceContext
EntityManager em;
...
public LineItem createLineItem(Order order, Product product,
int quantity) {
LineItem li = new LineItem(order, product, quantity);
order.getLineItems().add(li);
em.persist(li);
return li;
}
@OneToMany(cascade=ALL, mappedBy="order")
public Collection getLineItems() {
return lineItems;
}

2.2.4.2- Varlık Örnekleminin Silinmesi

Varlık örneklemlerinin yönetiminde silme işlemini yapmak için silme metodunu
kullanırız ya da cascade silme işlemini kullanırız. Bunu birebiriyle ilişkili varlıklarda
kullanırız. Eğer bu silme metodu yeni bir varlık tarafından çağırılıyorsa bu komut
askıya alınır. Eğer silme metodu Ayıran bir varlık tarafından çağırılıyorsa bu bir hata
oluşmasına sebep olur ne IllegalArgumentException fırlatır.
Public void removeOrder (Inteder orderId){
try {
Order order =em.find(Order.class,orderId)
em.remove(order);
}
}

2.2.5- Sorguların Oluşturulması

EntityManager.createQuery ve EntityManager.createNamedQuery metotları
Java Persistence sorgulama dillerindeki sorgulamaları kullanarak saklanmış bilgileri
sorgulamak için kullanılır.
CreateQuery metodu dinamik sorgular yaratmak için kullanılır.
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.setMaxResults(10)
.getResultList();
}
CreateNamedQuery metodu ise statik sorgular yaratmak için kullanılır. Bu sorgular
javax.persistence.NamedQuery de tanımlıdır.
@NamedQuery(
name="findAllCustomersWithName",
query="SELECT c FROM Customer c WHERE c.name LIKE
:custName"
)
Alt tarafta createNamedQuery metodunun kullanımına ait bir örnek var. Bu örnekteki
NamedQuery yukarıda tanımlanmıştır.

@PersistenceContext
public EntityManager em;
...
customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();

2.2.5.1- Sorgulardaki İsim Parametreleri

Parametre geçiren isimler javax.persistence.Query.setParamater (String
name, Object value) metodu kullanarak sınırlandırılırlar. Aşağıdaki örnekte
findWithName ve setParameter metodu kullanarak parametre geçiliyor.
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.getResultList();

2.2.5.2- Sorgulardaki Durumsal Parametreler

İsim yerine durumsal parametre de kullanılır. Kullanım yapısı (?) den sonra
gelen sayı gelen parametrenin sorgudaki yerini verir.Query.setParameter(integer
position ,Object value) bu metot parametre geçmek için kullanılır.
public List findWithName(String name) {
return em.createQuery(
“SELECT c FROM Customer c WHERE c.name LIKE ?1”)
.setParameter(1, name)
.getResultList();
}
Giriş parametreleri 1. giriş parametrelerinden sıralanmaya başlar.

2.3- Persistence Birimleri

Persistence bolumu varlık yöneticisi örnekleri tarafından yönetilen bütün varlık
sınıflarını tanımlar.Bu varlık grupları tek bir bilgi deposunda bulunan bilgileri temsil
eder.

tanımlanır.META-INF dizini persistence.xml içeren JAR dosyası ya da dizini,
persistence bölümünün kaynağı olarak adlandırılır.
Persistence bölümünün çalışma alanı persistence bölümünün kaynağı tarafından
belirlenir.Her bir persistence bolumu kendi çalışma alanına özel bir isimle
tanımlanmak zorundadır.
Persistence bölümleri WAR ya da EJB JAR dosyalarını parçası olarak birlikte
kullanılabilir.Ayrıca WAR ya da EAR dosyalarının içine eklenebilecek bir JAR dosyası
olarak da birlikte kullanılabilir.
Eğer persistence bölümünü bir grup olarak bir EJB JAR dosyası içinde
kullanırsanız, persistence.xml EJB JAR in META-INF dizini içine yerleştirilmelidir.
Eğer persistence bölümünü bir grup olarak bir WAR dosyası içinde kullanırsanız,
persistence.xml WAR dosyasının WEB-INF/classes/META-INF dizini içine
yerleştirilmelidir.
Eğer persistence bölümünü WAR ya da EAR dosyası içine dahil edilecek bir
JAR dosyası içinde kullanırsanız, JAR dosyası aşağıdaki bölümlerden birisine
yerleştirilmelidir.

- WAR in WEB-INF/lib dizini
- Bir EAR dosyasının en üst seviyesi
- EAR dosyalarının kütüphane dizini

2.3.1- Persistence.xml Kütüğü

Persistence.xml bir ya da birçok persistence birimi tarafından tanımlanır.
Aşağıdaki örnek bir persistence.xml kütüğüdür.


This unit manages orders and customers.
It does not rely on any vendor-specific features and can
therefore be deployed to any persistence provider.

jdbc/MyOrderDB
MyOrderApp.jar
com.widgets.Order
com.widgets.Customer


Persistence bölümleri persistence.xml konfigürasyon dosyası tarafından

Bu dosyanın içinde OrderManagement denilen bir persistence parçası tanımlıdır ve
JTA tarafından kullanılırlar. JAR dosyası ve sınıf elemanları persistence sınıflarını
yönetirler .

No comments:

Post a Comment