12. [TD]: [DAO] katmanının TD ile [Spring Data] kullanılarak uygulanması
Anahtar kelimeler: çok katmanlı mimari, Spring, bağımlılık enjeksiyonu, API JPA (Java Persistence API), Spring Data.
TD'in [DAO] katmanını uygulamak için önceki adımlarla aynı süreci izleyeceğiz.
12.1. Support
![]() |
- [1]'te, [support / chap-12] klasörü bu bölümün Eclipse projesini içerir;
12.2. Eclipse projesi
Eclipse projesi şu şekilde olacaktır:
![]() |
- [elections.dao.config]: Spring projesinin yapılandırma sınıfını içerir;
- [elections.dao.entities]: JPA varlıklarını ve projenin istisna sınıfını içerir;
- [elections.dao.repositories]: [CONF] ve [LISTES] tabloları için [CrudRepository] arayüzlerini içerir;
- [elections.dao.service]: [DAO] katmanının uygulamasını içerir. Yazmamız gereken bu sınıftır;
- [elections.dao.console]: [console] türünde bir test sınıfı içerir;
- [pom.xml]: Maven projesinin yapılandırma dosyasıdır;
Bu proje aşağıdaki mimariyi uygular:
![]() |
[DAO] katmanı, yalnızca [Spring Data] tarafından uygulanan katmanı görür.
12.3. Maven Yapılandırması
Yapılması gereken iş: Projenin [pom.xml] dosyasını derleyin.
12.4. [JPA] katmanındaki varlıklar
![]() |
![]() |
- [ElectionsConfig], [CONF] tablosundaki bir satıra ait nesne modelidir;
- [ListeElectorale], [LISTES] tablosundaki bir satıra ait nesne modelidir;
- [AbstactEntity], önceki iki sınıfın üst sınıfıdır. Bu sınıf, her iki sınıfa ortak olan [id, version] alanlarını bir araya getirir;
- [ElectionsException], projenin istisna sınıfıdır;
12.4.1. [ElectionsException] sınıfı
![]() |
[ElectionsException] sınıfı, 4.3. paragrafında açıklanan kontrol edilemeyen istisnadır.
12.4.2. [AbstractEntity] sınıfı
![]() |
[AbstractEntity] sınıfı şöyledir:
package elections.dao.entities;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@MappedSuperclass
public abstract class AbstractEntity implements Serializable{
private static final long serialVersionUID = 1L;
// özellikler
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
protected Long id;
@Version
@Column(name = "VERSION")
protected Long version;
// yapıcılar
public AbstractEntity() {
}
public AbstractEntity(Long id, Long version) {
this.id = id;
this.version = version;
}
// [equals] ve [hashcode] yeniden tanımlama
@Override
public int hashCode() {
return (id != null ? id.hashCode() : 0);
}
@Override
public boolean equals(Object entity) {
if (!(entity instanceof AbstractEntity)) {
return false;
}
String class1 = this.getClass().getName();
String class2 = entity.getClass().getName();
if (!class2.equals(class1)) {
return false;
}
AbstractEntity other = (AbstractEntity) entity;
return id != null && this.id == other.id;
}
// imza jSON
public String toString() {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(this);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
// alıcı ve ayarlayıcılar
...
}
Bu, 11.3.5.2. paragrafında açıklanan sınıftır, ancak jSON filtreleri hariçtir. Burada, [CONF] ve [LISTES] tabloları bir yabancı anahtar ilişkisi ile birbirine bağlı değildir. Oysa [lazy loading] modu ile böyle bir ilişkinin varlığı, jSON filtrelerinin gerekliliğini ortaya çıkarır.
12.4.3. [ElectionsConfig] sınıfı
![]() |
[ElectionsConfig] sınıfı, [CONF] tablosuyla ilişkili JPA varlığıdır;
Yapılması gereken iş: [ElectionsConfig] sınıfını oluşturun.
12.4.4. [ListeElectorale] sınıfı
![]() |
[ListeElectorale] sınıfı, [LISTES] tablosuyla ilişkili JPA varlığıdır;
Yapılması gereken iş: [ListeElectorale] sınıfını oluşturun.
12.5. [Spring Data] katmanı
![]() |
Yapılması gereken iş: [Spring Data] sınıfının, [CONF] ve [LISTES] tablolarını yönetmek için gerekli iki arayüzünü yazın;
12.6. [DAO] katmanı
![]() |
[DAO] katmanının [IElectionsDao] arayüzü şu şekildedir:
package dao.service;
import dao.entities.ElectionsConfig;
import dao.entities.ListeElectorale;
public interface IElectionsDao {
// seçim yapılandırması
public ElectionsConfig getElectionsConfig();
// aday listeleri
public ListeElectorale[] getListesElectorales();
// aday listelerinin güncellenmesi
public void setListesElectorales(ListeElectorale[] listesElectorales);
}
Yapılması gereken iş: [IElectionsDao] arayüzünün [ElectionsDaoJpa] uygulamasını yazın.
12.7. Spring projesinin yapılandırılması
[DaoConfig] sınıfı, Spring projesini yapılandırır.
Yapılması gereken iş: [DaoConfig] sınıfını yazın
12.8. [console] katmanı
![]() |
![]() |
[Main] sınıfı, aşağıdaki yürütülebilir sınıftır:
package dao.console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import dao.config.AppConfig;
import dao.entities.ElectionsConfig;
import dao.entities.ListeElectorale;
import dao.service.IElectionsDao;
public class Main {
// veri kaynağı
private static IElectionsDao dao;
public static void main(String[] args) {
// Spring bağlamının alınması
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// veri kaynağının alınması
dao = ctx.getBean(IElectionsDao.class);
// iki tablonun içeriği
ElectionsConfig electionsConfig = dao.getElectionsConfig();
ListeElectorale[] listes = dao.getListesElectorales();
// görüntüleme
System.out.println(String.format("Nombre de sièges à pourvoir : %d", electionsConfig.getNbSiegesAPourvoir()));
System.out.println(String.format("Seuil électoral : %5.2f", electionsConfig.getSeuilElectoral()));
System.out.println("Listes candidates----------------");
for (ListeElectorale liste : listes) {
System.out.println(liste);
}
// Spring bağlamının kapatılması
ctx.close();
}
}
[Test01] sınıfı, JUnit'in bir testidir:
package dao.tests;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import dao.config.AppConfig;
import dao.entities.ElectionsConfig;
import dao.entities.ListeElectorale;
import dao.service.IElectionsDao;
@SpringApplicationConfiguration(classes = AppConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class Test01 {
// [DAO] katmanı
@Autowired
private IElectionsDao electionsDao;
@Before
public void init() {
// [LISTES] tablosu temizleniyor
// rekabet halindeki listeler
ListeElectorale[] listes = electionsDao.getListesElectorales();
// oy ve koltuk sayılarını 0'a sıfırlayıp false olarak siliniyor
int voix = 0;
int sièges = 0;
boolean elimine = false;
for (ListeElectorale liste : listes) {
liste.setVoix(voix);
liste.setSieges(sièges);
liste.setElimine(elimine);
}
// [dao] katmanı sayesinde bu verileri kalıcı hale getiriyoruz
electionsDao.setListesElectorales(listes);
}
@Test
public void testElections01() {
System.out.println("testElections01-------------------------------------");
// seçim yapılandırmasının alınması
ElectionsConfig electionsConfig = electionsDao.getElectionsConfig();
int nbSiegesAPourvoir = electionsConfig.getNbSiegesAPourvoir();
double seuilElectoral = electionsConfig.getSeuilElectoral();
Assert.assertEquals(6, nbSiegesAPourvoir);
Assert.assertEquals(0.05, seuilElectoral, 1E-6);
// yarışan listeler
ListeElectorale[] listes = electionsDao.getListesElectorales();
// okunan değerlerin görüntülenmesi
System.out.println("Nombre de sièges à pourvoir : " + nbSiegesAPourvoir);
System.out.println("Seuil électoral : " + seuilElectoral);
System.out.println("Listes en compétition ---------------------");
for (int i = 0; i < listes.length; i++) {
System.out.println(listes[i]);
}
// listelere oy ve sandalye tahsis ediliyor
int voix = 0;
int sièges = 0;
boolean elimine = false;
for (ListeElectorale liste : listes) {
liste.setVoix(voix);
liste.setSieges(sièges);
liste.setElimine(elimine);
voix += 10;
sièges += 1;
elimine = !elimine;
}
// bu veriler [dao] katmanı aracılığıyla kalıcı hale getiriliyor
electionsDao.setListesElectorales(listes);
// veriler yeniden okunur
ListeElectorale[] listesElectorales2 = electionsDao.getListesElectorales();
// okunan veriler kontrol edilir
Assert.assertEquals(7, listesElectorales2.length);
voix = 0;
sièges = 0;
elimine = false;
for (ListeElectorale liste : listes) {
Assert.assertEquals(voix, liste.getVoix());
Assert.assertEquals(sièges, liste.getSieges());
Assert.assertEquals(elimine, liste.isElimine());
voix += 10;
sièges += 1;
elimine = !elimine;
}
System.out.println("Listes en compétition ---------------------");
for (int i = 0; i < listes.length; i++) {
System.out.println(listes[i]);
}
}
}
Yapılması gereken iş: [console] ve [JUnit] testlerini [DAO] katmanınızda çalıştırın.
12.9. Projenin Maven arşivinin oluşturulması
11.3.12 numaralı paragrafta verilen örneği takip ederek, projenin Maven arşivini oluşturun.












