• Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim
KodEdu
  • Anasayfa
  • Eğitimler
    • JavaScript Eğitimi
    • Angular 2 Eğitimi
    • React.js Eğitimi
    • Java 8 Eğitimi
    • Java EE 7 Eğitimi
    • Spring Framework Eğitimi
    • Git Eğitimi
  • Online Eğitimler
    • Online React.js Eğitimi
    • Online Angular 2 Eğitimi
    • Online Spring Boot Eğitimi
  • Referanslar
  • Hakkında
  • İletişim

JCache – CacheLoader ve CacheWriter Kullanmak

  • Posted by Kodedu
  • Categories backend, Genel, JPA, Uncategorized, Yazılar
  • Date 19 Eylül 2014

Bir önceki yazıda JCache standardının temellerinden bahsetmiştik. (Bkz. JSR 107 – JCache Standardına İlk Bakış) Şimdi ise bu temel üzerinden CacheLoader ve CacheWriter yapılarını inceleyeceğiz.

JCache standardında temel olarak üç tip operasyon bulunmaktadır;

Ekleme
put, putAll, putIfAbsent, getAndPut

Getirme
get, getAll, getAndPut, getAndRemove, getAndReplace

Silme
remove, removeAll, getAndRemove

Varsayılan ayarlarda tüm bu operasyonlar Cache nesnesinin içerisinde anabellek üzerinde sürdürülmektedir.

CacheLoader
Getirme operasyonlarında, talep edilen verinin Cache içerisinde bulunmama durumunda ikincil bir verikaynağından alınabilmesi için tasarlanan bir arayüzdür.

no cacheloader.png
Figure 1. CacheLoader aktif değilken

Varsayılan ayarlarla anahtar(key) değerine göre değer(value) döndürülür. Değer bulunamıyorsa yokluğu temsilen null döndürülür.

with cacheloader.png
Figure 2. CacheLoader aktif iken

CacheLoader türünden bir nesne konfigürasyona eklendiğinde ise, talep edilen veri Cache alanında bulunmadığında (yani null olduğunda), CacheLoader içinde tanımlanan diğer bir verikaynağından veri sunulabilir. Buradaki verikaynağının ne olacağı ise tamamiyle geliştiricinin seçimine bağlıdır. (Örn: DB, NoSQL, HDFS, FS vb.)

CacheLoader Arayüzü
public interface CacheLoader<K, V> { (1)

  V load(K key); (2)
  Map<K, V> loadAll(Iterable<? extends K> keys); (3)

}
  1. K → anahtarın tipini, V → değerin tipini temsil eder.
  2. key değerine göre value döndürmelidir.
  3. key değerlerine göre key⇒`value` çiftlerini döndürmelidir.

CacheLoader bir ve birden çok key (anahtar) veriye göre değer ve değerler döndüren load ve loadAll metodlarına sahiptir. Aşağıda yer alan BackupReader sınıfı, CacheLoader arayüzünün uygulanışını içeren bir örnektir. Yükleme işlemini JPA kullanarak bir ilişkisel veritabanından yapmaktadır.

BackupReader – CacheLoader Uygulama Örneği
public class BackupReader implements CacheLoader<Long, Book> {

 private final EntityManager em = //..;

 private static final Logger logger = //..


 @Override (1)
 public Book load(Long isbn) {

    logger.info(isbn + " Cache içinde bulunamadı.");
    logger.info(isbn + " db'den yükleniyor.");
    Book found = em.find(Book.class, isbn);

    if (Objects.nonNull(found))
        logger.info(isbn + " db'den yüklendi.");
    else
        logger.info(isbn + " db'de de bulunamadı.");
    return found;


 }

 @Override (2)
 public Map<Long, Book> loadAll(Iterable<? extends Long> keys){

    Map<Long, Book> allBooks = new HashMap<>();

    for (Long key : keys) {
        allBooks.put(key, load(key));
    }

    return allBooks;
 }
}
  1. isbn numarasına göre kaydı DB’den yükler
  2. isbn numaralarına göre kayıtları DB’den yükler
cachewriter.png
Figure 3. CacheWriter aktif iken

CacheWriter yapılandırması yapıldığında, herhangi bir silme veya ekleme operasyonunda, aynı işlem diğer veri kaynağında da uygulanabilmektedir.

CacheWriter Arayüzü
public interface CacheWriter<K, V> {
 void write(Cache.Entry<K,V> entry); (1)
 void writeAll(Collection<Cache.Entry<K,V>> entries); (2)
 void delete(Object key); (3)
 void deleteAll(Collection<?> keys); (4)
}
  1. Bir K,V girdisini yazar.
  2. Birden fazla K,V girdisini yazar.
  3. key girdisine göre kaydı siler.
  4. key girdilerine göre kayıtları siler.

CacheWriter sınıfı hem yazma hem de silme operasyonlarını takip edebilecek metodlar bulundırmaktadır.

Aşağıda yer alan BackupWriter sınıfı, CacheWriter arayüzünün uygulanışını içeren bir örnektir. Yazma ve Silme işlemlerini JPA kullanarak bir ilişkisel veritabanından yapmaktadır.

BackupWriter – CacheWriter Uygulama Örneği
public class BackupWriter implements CacheWriter<Long, Book> {

 private final EntityManager em = //..
 private static final Logger logger = //..

 @Override
 public void write(Cache.Entry<Long,Book> entry){ (1)

    Long isbn = entry.getKey();
    Book book = entry.getValue();

    logger.info(isbn + " db'ye yazılıyor");

    em.getTransaction().begin();
        em.merge(book);
    em.getTransaction().commit();

    logger.info(isbn + " db'ye yazıldı");
 }

 @Override
 public void writeAll(Collection<Cache.Entry<Long,Book>> entries){
    entries.forEach(this::write); (2)
 }

 @Override
 public void delete(Object isbn) { (3)
    Book found = em.find(Book.class, isbn);

    if (Objects.nonNull(found)) {
        logger.info(isbn + " db'den siliniyor.");

        em.getTransaction().begin();
            em.remove(found);
        em.getTransaction().commit();

        logger.info(isbn + " db'den silindi.");
    }
 }

 @Override
 public void deleteAll(Collection<?> keys) { (4)
    keys.forEach(this::delete);
 }
}
  1. Cache’e yazılan `Book türünden bir nesneyi veritabanına yazar.
  2. Koleksiyon içeriği kadar (1)‘i tekrarlar.
  3. isbn (Key)’e göre Book türünden bir nesnesi veritabanından siler.
  4. Koleksiyon içeriği kadar (3)‘ü tekrarlar.

CacheLoader ve CacheWriter Aktifleştirmek

CacheLoader ve CacheWriter türünden yükleyicileri tanıtabilmek için Configuration sınıfının setWriteThrough ve setReadThrough metodlarına true parametresi gönderilmelidir.

Örneğin;
MutableConfiguration config = new MutableConfiguration();
..
config.setWriteThrough(true);
config.setReadThrough(true);
..

Write Through ve Read Through özellikleri açıldıktan sonra, bir üretici nesne (Factory) üzerinden CacheLoader ve CacheWriter nesneleri tanıtılmalıdır. Tanıtım işlemi Configuration sınıfının setCacheLoaderFactory ve setCacheWriterFactory metodları üzerinden yapılmaktadır.

Örneğin
MutableConfiguration config = new MutableConfiguration();
..
config.setCacheWriterFactory(()-> new BackupWriter());
// veya
config.setCacheWriterFactory(BackupWriter::new);

// -----------

config.setCacheLoaderFactory(()-> new BackupReader());
// veya
config.setCacheLoaderFactory(BackupReader::new);
..
Not
Bu örnekte Lambda deyimlerinden ve Method referans özelliklerinden faydalanılmıştır.

Uygulama Zamanı

Şimdi BackupReader ve BackupWriter kullanarak bir JCache uygulaması geliştirelim.

Uygulama Long türündeki isbn anahtarına göre Book türündeki nesne değerlerini tutacaktır.

Book Entity Sınıfı
@Entity
public class Book implements Serializable {

    @Id
    private Long isbn;

    private String name;

    private double price;

    // getter,setter,constructor metodları
}

Book sınıfı önbellekleme için kullanılacak bir JPA Entity sınıfıdır.

Not
Cache içerisine eklenen nesneler Serializable olmalıdır.

Uygulama içerisinde 123444L, 123445L ve 123446L isbn numaralı Book nesneleri Cache içerisine eklenmektedir.

Uygulama içerisinde eklenmeyen ama veritabanından bulunan ayrıca 123447L, 123448L ve 123449L isbn numaralı kayıtlar veritabanında bulunmaktadır.

CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();

MutableConfiguration config = new MutableConfiguration();
config.setTypes(Long.class, Book.class);

config.setWriteThrough(true);
config.setReadThrough(true);

config.setCacheWriterFactory(()-> new BackupWriter());
config.setCacheLoaderFactory(BackupReader::new);

Cache<Long, Book> kodcu = cacheManager.createCache("kodcu", config);

kodcu.put(123444L, new Book(123444L, "Java ve Yazılım Tasarımı", 35));
kodcu.put(123445L, new Book(123445L, "Java Mim. Kur. Çözümler", 25));
kodcu.put(123446L, new Book(123446L, "Java ve WebSocket", 30));

Book b1 = kodcu.get(123445L); // in Cache
Book b2 = kodcu.get(123447L); // not in Cache but in DB
Book b3 = kodcu.get(123999L); // neither in Cache nor DB

3 adet put ve 3 adet get isteğinden sonra Log çıktıları aşağıdaki gibi olmaktadır.

INFO: 123444 db'ye yazılıyor
INFO: 123444 db'ye yazıldı

INFO: 123445 db'ye yazılıyor
INFO: 123445 db'ye yazıldı

INFO: 123446 db'ye yazılıyor
INFO: 123446 db'ye yazıldı

INFO: 123447 Cache içinde bulunamadı.
INFO: 123447 db'den yükleniyor.
INFO: 123447 db'den yüklendi.

INFO: 123999 Cache içinde bulunamadı.
INFO: 123999 db'den yükleniyor.
INFO: 123999 db içinde de de bulunamadı.
  • Cache içerisine put ile atılan nesneler aynı zamanda veritabanına da kazınmaktadır.
  • Cache içerisinde var olan veriler Cache den sunulmaktadır.
  • Cache içerisinde var olmayan veriler ise Veritabanından sunulmaktadır.

Uygulama örneğine aşağıdaki bağlantıdan erişebilirsiniz

Örnek Uygulama

Tekrar görüşmek dileğiyle.

Tag:backend, cache, cachewriter, cahcereader, jcache

  • Share:
author avatar
Kodedu

Previous post

JSR 107 - JCache Standardına İlk Bakış
19 Eylül 2014

Next post

Ebook Hazırlama ve Yayınlama (Video + Sunum)
20 Eylül 2014

You may also like

api-logo
Swagger Nedir? Neden kullanılır?
10 Ekim, 2018
spring-cli-logo
Spring CLI ile Spring Boot Projeleri Hazırlamak
21 Ağustos, 2017
eureka_architecture
Spring Cloud Netflix ve Eureka Service Discovery
3 Temmuz, 2017

Leave A Reply Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta listesine kayıt olun!






Gözde yazılar

Java Mimarisiyle Kurumsal Çözümler : Kurumsal Java Kitabı
16Eyl2012
Java API for JSON Processing – Stream bazlı JSON Üretmek ve Tüketmek
06Ağu2013
AsciidocFX projesi Duke’s Choice Award 2015 ödülünü kazandı
28Eki2015
Knockout.js – Hesap Makinesi Örneği
02Şub2013

Son Yazılar

  • Java’da Record’lar 27 Ocak 2020
  • Swagger Nedir? Neden kullanılır? 10 Ekim 2018
  • Spring CLI ile Spring Boot Projeleri Hazırlamak 21 Ağustos 2017
  • Spring Cloud Netflix ve Eureka Service Discovery 3 Temmuz 2017
  • Online React.js Eğitimi ardından (15-25 Mayıs 2017) 31 Mayıs 2017

Son Yorumlar

  • Coupling ve Cohesion Kavramları Nedir? için Hilal
  • Naïve Bayes Sınıflandırma Algoritması için Rahman Usta
  • Naïve Bayes Sınıflandırma Algoritması için Mete
  • YAML Nedir? Neden YAML Kullanmalıyız? için kara
  • JWT (JSON Web Tokens) Nedir? Ne işe yarar? için Furkan

Get Java Software

Arşivler

Bizi takip edin

React.js Eğitimi Başlıyor
11-22 Eylül, 2017
Eğitmen
Rahman Usta
İletişim

merhaba@kodedu.com

  • Hakkında
  • Gizlilik Politikası
  • İletişim
  • Referanslar
Kodedu Bilişim Danışmanlık
Cemil Meriç mah. Çelebi sok.
No:16/3 Ümraniye/İSTANBUL
Tel: 0850 885 38 65
Alemdağ V.D.: 8960484815

KODEDU © Tüm hakları saklıdır.